Archive for the 'ColdFusion' Category
Problem Installing ColdFusion 8 on Snow Leopard
Wednesday, April 13th, 2011

I ran into a problem trying to install ColdFusion 8 on my MacBook Pro running Snow Leopard. I honestly don’t know the what the exact problem is, but from what I can gather, it has to do with Java and the crappy InstallAnywhere installer used for CF 8. To give credit where credit is due, the solution is taken from this site: http://www.doyourself.org/windows-2/786-install-coldfusion-8-on-snow-leopard/

The steps are simple:

  1. Open a Terminal
  2. cd “Downloads/ColdFusion Installer 8.app/Contents/Resources/Java”  (modify to fit the name/path of your installer file)
  3. java -cp ./IAClasses.zip:Execute.zip:installscript.zip:. com.zerog.ia.installer.Main
  4. Installer should launch, just install normally

Doing this allowed me to get through the install. I did it with CF 8 64 bit, but I checked an the 32 bit installer wouldn’t run for me either, so maybe this would work in that case too.

Lightwire Tutorial 2: AOP
Monday, March 15th, 2010

Now that I’ve gone over the basics of Lightwire as far as creating bean and injecting dependencies go, let’s get into some Aspect Oriented Programming (AOP). AOP is about addressing the separation of cross-cutting concerns from the main application functionality. Yeah, I know, the first time I read this, it came through as “blah blah blah [jargon here] blah blah blah.” So to simplify, cross-cutting concern just means some functionality that can apply to many parts of an application. The examples you’ll likely see over and over for this (and rightly so) are logging and security. Suppose you have a bunch of components/beans and you want to log method calls for several/all the methods in those beans. You could do something like this in a method:

<!--- Logger.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfreturn this />
	</cffunction>

	<cffunction name="log">
		<cfargument name="txt" type="string">

		<!--- Some code to write the log text to a file --->
		.....
	</cffunction>
</cfcomponent>

<!--- Controller.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfset variables.Logger = createObject("component", "Logger") />

		<cfreturn this />
	</cffunction>

	<cffunction name="doSomething">
		<cfset variables.Logger.log("Function doSomething() ran.") />

		<!--- A bunch of code here doing amazing things! --->
		.....
	</cffunction>
</cfcomponent>

Now think of having to do it for 75 beans with an average of 7 methods in each. Are you feeling the pain? Or what if you suddenly needed to apply security to certain parts of a site running on an MVC framework. Imagine your controller:

<!--- Security.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfset variables.Security = createObject("component", "Security") />

		<cfreturn this />
	</cffunction>

	<cffunction name="hasSuperExtraMegaSecretClearance">
		<!--- Some code to test if the user is the director of the CIA --->
		.....
	</cffunction>
</cfcomponent>

<!--- Controller.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfreturn this />
	</cffunction>

	<cffunction name="uncoverKennedyAssassinationPlot">
		<cfif variables.Security.hasSuperExtraMegaSecretClearance()>
			<!--- Some code to load all that stuff from the databases at Langley --->
			.....
		</cfif>
	</cffunction>
</cfcomponent>

Now think about adding that cfif for all the methods that pertain to Area 51. Sounds like a great way to lose your sanity. Enter AOP! AOP will allow you to do all these things and avoid that stream of curses that would undoubtedly result from your boss telling you “Listen Bob, I have this project I need you to work on…” For instance, let’s take a look at the first scenario using Lightwire and AOP. In the code below, assume that the Logger.cfc file is exactly the same as the one above.

<!--- Controller.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfreturn this />
	</cffunction>

	<cffunction name="doSomething">
		<!--- A bunch of code here doing amazing things! --->
		.....
	</cffunction>
</cfcomponent>

<!--- LogAdvice.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfargument name="Logger" type="any">

		<cfset variables.Logger = arguments.Logger />

		<cfreturn this />
	</cffunction>

	<cffunction name="before" returntype="string">
		<cfargument name="method" type="string">
		<cfargument name="args" type="struct">
		<cfargument name="target" type="any">

		<cfset variables.Logger.log("Function #arguments.method#() ran.") />
	</cffunction>
</cfcomponent>

<!--- BeanConfig.cfc --->
<cfcomponent extends="lightwire.BaseConfigObject" hint="A LightWire configuration bean.">
	<cffunction name="init" output="false" returntype="any" hint="I initialize the config bean.">
		<cfscript>
		// Call the base init() method to set sensible defaults. Do NOT remove this.
		Super.init();

		// OPTIONAL: Set lazy loading: true or false. If true, Singletons will only be created when requested. If false, they will all be created when
		//LightWire is first initialized. Default if you don't set: LazyLoad = true.
		setLazyLoad("false");

		// BEAN DEFINITIONS (see top of bean for instructions)
		addSingleton("cfcPath.Controller");
		addSingleton("cfcPath.Logger");
		addSingleton("cfcPath.LogAdvice");

		// Depency Injection
		addConstructorDependency("LogAdvice", "Logger");

		// AOP Advice
		addBeforeAdvice("Controller", "Logger", "doSomething");
		</cfscript>

		<cfreturn this />
	</cffunction>
</cfcomponent>

As you can see, the logging code has been completely removed from the original Controller.cfc file. The Lightwire config file is fairly straightforward. The Controller bean, Logger bean, and a new LoggerAdvice bean get defined with addSingleton() calls. Once defined, a Before advice is used to tell Lightwire that you want method “before” (it’s the default method for Before advice) from bean “Logger” to run before the method “doSomething” in bean “Controller” when it is called. Simple, right? For this one case, it can seem like overkill, but if you have a lot of logging to do, it’ll save you a lot of time. Note that if you wanted to log every function call in the Controller bean, you could just put “*” as the third argument instead of “doSomething”, and you can also ue a comma-delimited list of functions. If there were more beans you needed to do logging for, you would just need to add an addBeforeAdvice() call for that other bean. This may seem like a problem if you have a lot of beans, but thanks to the programmatic nature of the Lightwire configuration, it’s usually easy to loop through all the CFCs in a directory, add a singleton for each, and add the advice for each. Also, while I think the LoggerAdvice bean is recommended in this case to keep the generic Logger functionality (you may be using it for other things than logging method calls), you could technically only have a Logger bean and define a before() method in it, eliminating the need for the LoggerAdvice.

Now, let’s move on to the second example. Here’s how you could implement the security using AOP and an Around advice:

<!--- Controller.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfreturn this />
	</cffunction>

	<cffunction name="uncoverKennedyAssassinationPlot">
		<!--- Some code to load all that stuff from the databases at Langley --->
		.....
	</cffunction>
</cfcomponent>

<!--- SecurityAdvice.cfc --->
<cfcomponent>
	<cffunction name="init">
		<cfargument name="Security" type="any">

		<cfset variables.Security = arguments.Security />

		<cfreturn this />
	</cffunction>

	<cffunction name="around" returntype="string">
		<cfargument name="AdviceDispatcher" type="any">

		<cfif variables.Security.hasSuperExtraMegaSecretClearance()>
			<cfset arguments.AdviceDispatcher.run()>
		</cfif>
	</cffunction>
</cfcomponent>

<!--- BeanConfig.cfc --->
<cfcomponent extends="lightwire.BaseConfigObject" hint="A LightWire configuration bean.">
	<cffunction name="init" output="false" returntype="any" hint="I initialize the config bean.">
		<cfscript>
		// Call the base init() method to set sensible defaults. Do NOT remove this.
		Super.init();

		// OPTIONAL: Set lazy loading: true or false. If true, Singletons will only be created when requested. If false, they will all be created when
		//LightWire is first initialized. Default if you don't set: LazyLoad = true.
		setLazyLoad("false");

		// BEAN DEFINITIONS (see top of bean for instructions)
		addSingleton("cfcPath.Controller");
		addSingleton("cfcPath.Security");
		addSingleton("cfcPath.SecurityAdvice");

		// Depency Injection
		addConstructorDependency("SecurityAdvice", "Security");

		// AOP Advice
		addAroundAdvice("Controller", "Security", "uncoverKennedyAssassinationPlot");
		</cfscript>

		<cfreturn this />
	</cffunction>
</cfcomponent>

This case is similar to the first, except this time we’re using an Around advice. Around advice gives you more complete control over method execution, it’s kind of a Before and After advice rolled into one. The AdviceDispatcher argument it receives allows you to retrieve info about the method and bean that is being advised, as well as control the timing of the execution of the original method. You could even decide, depending on logic, that you don’t want to execute that method at all. And again, if you need to apply security to many different parts of your app, it’s easy to use this and apply it to multiple beans/method in a generic way.

As a side note, it’s worth mentioning that while I use Lightwire because it’s the project I’m contributing to, all this is applicable to ColdSpring, which offers the same types of advice. The difference is that you’d have to define your beans, dependencies, and advices in XML and if I remember correctly your beans have to extend certain components. But it’ll get the same job done. Also, it’s worth noting that AOP is not yet in the main distribution of Lightwire (see my previous post on AOP in Lightwire), it’s only available here until it’s further vetted. Feel free to download it from the Download section and give it a try. Any feedback is very appreciated.

I hope that from these examples you’re able to see both the power and convenience that AOP can provide you with, and how to use Lightwire to achieve those results.

Lightwire Tutorial 1: The Basics
Friday, March 12th, 2010

Following up on my last post regarding Lightwire Aspect Oriented Programming (AOP), I thought I’d write up some tutorials to help people get familiaried with Lightwire itself, since I didn’t see a ton of info around. The harder part is actually getting comfortable with the concepts of dependency injection and AOP. Once you got those figured out, Lightwire is stupidly easy to use.

In this post, I’ll cover the concept of dependency injection and leave AOP for another post. Dependency injection is basically a way to ensure that your code is more loosely coupled. As it turns out, it can also make it a heck of a lot easier to use your objects. As an example, I’ll use something simple that will hopefully demonstrate the concept well. I’m going to take a simple service bean (a bean is just a CFC) and a logger bean and show different ways to make them work together. The service bean could do anything, its functionality is irrelevant to this example.

<!--- Logger.cfc --->
<cfcomponent>
	<cffunction name="init" returntype="Logger">
		<cfreturn this />
	</cffunction>

	<cffunction name="log" returntype="void">
		<cfargument name="text" type="string" />

		<!--- Here there would be some code to log things somewhere (a file, DB, etc.) --->
		</cffunction>
	</cfcomponent>

The above illustrates highly coupled components. What’s wrong with it? Technically speaking, nothing. It won’t throw errors or anything (unless I screwed up something!) But the two components are tightly coupled. Imagine if you want to change the class you use for logging? In this simple scenario, it’s pretty simple, all you need to do is change that one call, but what if you have 100 service beans and all of them use the Logger bean? It becomes a bit more painful, right? OK, OK, you could do a Find/Replace in your IDE, but you catch my drift. The other problem is that you will need to manually instantiate the logger bean in every component, which is tedious and violates the DRY principle. Finally, you sometimes want a bean to be a singleton, meaning there’s only one instance of it for the entire application. You need something to manage that.

Here’s another way to go about it (the logger component stays the same so I won’t repeat it here, assume it’s the same as the one above):

<!--- Service.cfc --->
<cfcomponent>
	<cffunction name="init" returntype="Engine">
		<cfargument name="logger" type="Logger" required="yes" />

		<cfset variables.logger = arguments.logger />

		<cfreturn this />
	</cffunction>

	<cffunction name="doSomething" returntype="void">
		<cfset variables.logger.log("Hello world!") />

		<!--- Perform more actions here, anything --->
	</cffunction>
</cfcomponent>

<!--- ServiceFactory.cfm --->
<cfcomponent>
	<cffunction name="init" returntype="ServiceFactory">
		<cfreturn this />
	</cffunction>

	<cffunction name="getService" returntype="Service">
		<cfif NOT structKeyExists(variables, "service")>
			<cfset variables.service = createObject("component", "Service").init( createObject("component", "Logger").init() ) />
		</cfif>

		<cfreturn variables.service />
	</cffunction>
</cfcomponent>

Using the above, things are a little better. The Service bean receives the Logger bean when created and doesn’t have to worry about how it gets instantiated. However, you’re still left with the tedious task of creating the factory, instantiating the Logger manually, etc. Imagine if you wanted the logger to behave similarly. You’d have to create a factory for it to. And imagine if the logger object had dependencies of its own. You can see how this can get really ugly. That’s when a dependency framework comes to the rescue. Here’s how you would do things with lightwire:

<!--- BeanConfig --->
<cfcomponent extends="lightwire.BaseConfigObject" hint="A LightWire configuration bean.">

	<cffunction name="init" output="false" returntype="any" hint="I initialize the config bean.">
		<cfset addSingleton("cfcPath.Service", "Service") />
		<cfset addSingleton("cfcPath.Logger") />
		<cfset addConstructorDependency("Service", "Logger") />

		<cfreturn this />
	</cffunction>

</cfcomponent>

<!--- index.cfm --->
<cfset config = createObject("component","cfcPath.BeanConfig").init() />
<cfset lightwire = createObject("component","lightwire.LightWire").init(config) />

<cfset service = lightwire.getBean("Service") />

In the example above, assume that Logger.cfc is the same as the first example and Service.cfc is the same as the second example. With that out of the way, here’s what’s happening in the above. In the configuration bean, you’re giving Lightwire the definition for your beans. The addSingleton() function is used to define a singleton bean, and you could use addTransient() in the same way to define a transient bean. Within that function call, you specify the path of the component in the first argument and the name of the bean as the second. If the name of the bean is the same as the last part of the path, you don’t need to specify it. You then use the addConstructorDependency() to wire the beans together. The first argument is the bean you want to inject something into, the second is the bean to inject. Then the index.cfm file shows how to start Lightwire and get a bean from it. So the getBean() call basically retrieves a bean based on the configuration above. So behind the scene, something is happening to do createObject(“component”, “cfcPath.Service”).init(createObject(“component”, “cfcPath.Logger”).init()); without you having to type all that. Imagine how useful that is when you have tons of beans with lots of dependencies, that are reused in many other beans. Priceless. Note that since we defined the beans as singletons Lightwire will only instantiate them once in its lifetime. So if you store Lightwire in a persistent scope, like the application scope, your beans will only get created once, saving you the overhead of creating them over and over.

There are 3 ways to inject beans in Lightwire. The first is the one described above, using a constructor dependency. In that case, you add an argument to your bean’s init() function matching the name of the bean to be injected (or you can specify a different name as the third argument of the addConstructorDependency() function). A second way is a setter injection. For a setter injection, you would use addSetterDependency() function. The arguments are the same as for the constructor function, but to get the bean injected you need to define a method in the receiving bean named “set[BeanName]“. Finally, there’s mixin injection. You can add a mixin dependency by using the addMixinDependency() function, which works exactly like the other two, the difference is you don’t need to do anything in the receiving bean. The injection will be done behind the scenes and you don’t have to worry about a thing.

How do you know which injection type to use? It really depends. If you have two beans that both depend on each other, you can’t use constructor dependency, otherwise you’ll run into a circular reference problem. So you can use setter or mixin dependencies in those cases. If you need to use the injected bean in the init() method of the receiving bean, you’ll probably want to use constructor injection. Then it’s down to preference. Some people don’t like mixin injection because they feel it hides part of the implementation and can be confusing to an outsider looking at your application. But I find it invaluable, saves me from adding all those constructor arguments or setter methods. When I have a bean I want to inject pretty much everywhere (like a Utility bean, for example), I usually use mixin injection.

You can also inject regular properties using addConstructorProperty(), addSetterProperty(), and addMixinProperty(). All those take 3 arguments, the name of the bean, the name of the property, and the value of the property.

So this ought to cover the basics of DI and how to use Lightwire for that purpose. Stay tuned for a post on Lightwire and AOP (I’ve already done one, but I’m gonna try to make one that’s actually clear!)