Note: I just noticed, maybe it's something just added in 1.1.0 or later builds, but they have the assembly plugin integrated with the Roo Shell perform command. So you can do perform assembly and actually get an assembled jar with all dependencies. WOOT. Anyway, this is still useful for those who want to run Maven headless projects.Let's say you want to use Spring Roo to do persistence work, but you don't need a website. Maybe it's just a utility, something that, say uses iText to generate PDF files, or does some data processing, job execution, or some other headless task.
Spring Roo is built using Maven, and the build target generally start in an initial Roo project by deploying a JAR file, until you add Spring MVC by adding a controller. In Maven, the output of a given build is generally one thing, (the jar) so running the project might involve downloading a ton of JAR files to add to a very big classpath. That's a lot of work.
Alternatives - Maven Packaging Plugins
There are a number of maven packaging plugins that can assemble a Jar that includes all of your classes and property files from various source Jars. Several, including the Maven assembly plugin, and the one-jar plugin, didn't work for me out of the gate due to some problems loading some of the SpringSource XML schemas and extender languages.
The challenge is that these special files, META-INF/spring.handlers and META-INF/spring.schemas, are included in each of the extension JARs (like Spring Security, Spring MVC, JMS, etc) so that you can issue commands like this:
<mvc:annotation-driven />
These tools generally copy files into a temp directory and then jar it up, so they overwrite these files each time.
The Shade Plugin
The
Maven shade plugin has a nice feature called a transformer. There is a special AppendingTransformer class that can be configured to continue to append data into a file specified in the configuration. Based on
this article from Hagel Blog, I added two entries to the plugin configuration (as commented below) to fix the two META-INF files and we were in business.
So, without further adieu, here are the steps to single-jar happiness (at least so far) with Spring Roo and the Maven Shade plugin:
Step 1: Install the Shade Plugin to your pom.xml file
Using your STS or favorite editor, go to your maven build file, pom.xml, and add the following entry to the build -> plugins section (THANK YOU, Hagel Blog, for figuring out the problem with Spring's namespace files!):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.
resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.
resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</plugin>
Step 2: Run your maven build
Now you can just issue a mvn package command, which will package up your content in the JAR file directly.
Step 3: Execute your JAR
Go ahead now and cd to target, and issue a command like:
java -classpath ./artifact-jar-file-name.jar package.path.and.mainclassname
And that's it. Pretty nifty feature, no? Let me know if you've had success or problems with this approach.