I have to deal with what is pretty ugly and large blob of ColdFusion code which up to this day is maintained by direct modifications on production server (don't ask). I managed to clean it up from dupes and backups and put it into Subversion, now I need tp pick a make system to be able to put this onto continuous build (TeamCity) and also scheduled releases. To my surprise I only found pretty much a single blog article on how to retrofit CF project with Maven, so the question is - does anyone have experience successfully using Maven on CF and what in general people use to manage large CF projects? Your suggestions, tips and links will be much appreciated Since I don't want to start religions wars - Maven is pretty much company standard (vs Ant)
First, here's another blog you might find helpful.
build-tools-maven-and-coldfusion
I haven't tried to build ColdFusion with Maven, but I have experience with managing Maven builds for a large company. There are a few things for you to consider.
Project structure
Coldfusion cfm and cfc files should be put in src/main/resources so they are bundled in the jar (the blog referenced above overrides the Maven convention to put them in src. this is ok, but could be a problem if you later need to add anything else to the project).
I'd probably keep cfc and cfm files in separate projects with appropriate dependency declarations to link them, this keeps your cfc projects as libraries and helps reuse. It is also worth considering the granularity of the cfc projects. Generally Maven's dependency management helps you keep artifacts small, with little need to worry about finding all the jars.
Deployment
The simplest way to deliver the artifacts is to use the maven-war-plugin to create a war containing your artifacts and all their transitive dependencies. This makes each application self-contained, which can be useful. The downside of this is that you'll end up bundling the same artifacts repeatedly and they can be quite large. To mitigate this you can either use the assembly-plugin to create custom packages excluding the common components, or you can specify that certain components (e.g. ColdSpring) are scope provided, this means they won't be included in the war.
Version Management
Maven encourages a proliferation of dependencies, by default each dependency declaration has a version, this can cause maintenance issues, particularly when you want to bump the version of an external dependency. You can mitigate this by defining a parent POM or an "app" POM. Either would have a dependencyManagement section declaring the details (groupId, artifactId, and version) for common artifacts. Any POM inheriting from the parent need not declare the dependency version as it will be inherited (note this doesn't mean that all children will have all dependencies, only that any that declare a dependency don't need to declare the version). If you define an "app" project with packaging "pom" and a dependencyManagement section, you can reference it with scope import (from Maven 2.0.9 onwards), this will import the dependencyManagement section from the "app" project to the project POM. See the dependency documentation for more details.
If you declare a dependency with a scope in the dependencyManagement section, that scope will be inherited unless it is overridden in the child POM. Related to the deployment section above, this means that you can declare the common libraries scope provided in the parent to ensure they are not bundled in each applciation.
Naming Conventions You'll need a naming convention for the packages to avoid collisions. It's probably best to follow the Maven convention and use java package-like groupIds (org.apache.maven for maven.apache.org) and the jar name for the artifact. This convention would give the groupId "org.coldspringframework" and artifactId "coldspring" for ColdSpring.
Further distinctions might need to be made across the company. For example, if you have a web and core team, you could give the web team the groupIds com.mycompany.web.* and the core team com.mycompany.core.*
Dependency Management
You'll need to add your CFC packages to a Maven repository such as Nexus so they are accessible to other builds across the enterprise.
If you want to keep the CFC packages separate to the jars. You can specify a custom packaging type, so that they won't be mixed up with any Java artifacts. If you create a custom packaging type, the artifacts can have the ".jar" extension, but any dependency declaration must have the type set.
Here's an example following those conventions:
<dependency>
<groupId>org.coldspringframework</groupId>
<artifactId>coldspring</artifactId>
<version>1.2</version>
<!--custom packaging type helps keep separate from Java artifacts-->
<type>cfc</type>
</dependency>
There's a section in the Nexus book that describes custom lifecycles (follow the links for more details. Essentially you need to create a plugin with a META-INf/plexus/components.xml to describe the plexus mechanics (what archiver to use, what extension to output etc).
The components.xml would look something like this:
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>cfc</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
<package>com.hsbc.maven.plugins:maven-jar-plugin:jar</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>cfc</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
<configuration>
<extension>jar</extension>
<type>cfc</type>
<packaging>cfc</packaging>
</configuration>
</component>
<component>
<role>org.codehaus.plexus.archiver.Archiver</role>
<role-hint>cfc</role-hint>
<implementation>org.codehaus.plexus.archiver.zip.ZipArchiver</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
</component>
<component>
<role>org.codehaus.plexus.archiver.UnArchiver</role>
<role-hint>cfc</role-hint>
<implementation>org.codehaus.plexus.archiver.zip.ZipUnArchiver</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
</component>
</components>
</component-set>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With