This is a very nice way to have your application bundled because all applications have to follow the same standard, and the deployment strategy should also look very familiar to developers accustomed to servlet containers and application servers, such as Apache Tomcat.
With the introduction of Mule 3, a new deployment strategy was introduced. Applications need to be zipped (exploded applications are supported as well) and need to follow a specific standard. The main Mule configuration file must be called mule-config.xml and must be in the main directory of the zip file. Dependencies must be placed under the folder /lib, while any classes which are not part of a JAR must be placed under /classes.
Many applications nowadays are managed by Apache Maven which is a project management tool, capable of working out all the transitive dependencies of your application based on a set of dependencies you jot down in pom.xml.
The following is an example of a particular project’s dependency set written for Maven:
This POM denotes that our application is using Mule 3.1, with some modules and transports, together with the Mule functional tests. It also points out that our project uses Apache Derby DB, Commons DBCP and MyBatis (core and Spring support for MyBatis). Finally, the plugin at the very end lets Maven know that our project must be compiled using Java 1.6, mostly because we make heavy use of Java Annotations.
After configuring our project, if we run mvn package in the terminal or command line, we get as a result a JAR file of our application. Although this is very useful, it is still a long way from our ultimate goal; a zip file with all dependencies and the mule-config.xml in their correct respective locations.
MuleSoft thought about this and created a new package of type Mule, so if you replace the above <packaging>jar</packaging> with <packaging>mule</packaging> and add the appropriate plugin in the pom, then when you execute the mvn package, you will get a zip file with the correct deployment. However, there is a problem with this packaging. Since the final result of the packaging is a zip file, you will not be able to create other projects which depend on this project. The maven dependency will not work correctly. In this blog, we show you a work around.
Luckily Maven provides a plugin to create packages, these are called Maven Assemblies. Even more useful, one particular maven assembly plugin creates packages that include the dependencies, called jar-with-dependencies. We can make use of this plugin with some tweaking to reach our final objective.
First, we must denote in the pom.xml file that we have an assembly configuration. This is done by adding the following snippet in the <plugins> section.
Our configuration says that the Maven Assembly configuration can be found in assembly.xml. Lets take a look at the assembly configuration and go through it…
This requires at least Maven 2.2.1 to work correctly.
To use the existing jar-with-dependencies plugin, all we have to do is denote it in the id tag. The format tag lets the assembly know how we want our final package arranged, in our case, we want a zip file. The includeBaseDirectory must be set to false otherwise the final product will be placed inside another directory, this means that mule-config.xml will not be in ‘/’, but in a folder carrying the name of the application.
The interesting bits start here; we need to tell the assembly where our mule-config.xml is and where we must place it. This is achieved through the fileSets configuration and as configured above, we can see that we are pulling mule-config.xml from src/main/resources and placing it into ‘/’.
Finally we add our dependencies into dependencySets. There are two very important configurations here to do, first we want our dependencies to be placed in the /lib folder, and most importantly, we do not want to include the Mule dependencies (and its transitive dependencies) since they will already be present in the Mule installation. Also we want to avoid adding the transitive Spring dependencies pulled in my MyBatis-Spring since they are already in the Mule installation, but MyBatis-Spring uses a different version. This is all done by the configuration in the tags outputDirectory, excludes and useTransitiveFiltering.
Now at this point, we need to add our own application to the final artifact, there are two ways to do this, we can either add the compiled classes in /classes, or we can add the Maven packaged JAR into /lib with the dependencies. In this assembly, we opted for the second option, and this is done by setting the useProjectArtifact to true. The other option is to add another fileSet tag and include the *.class files, and *.xml if you have other configuration files.
To generate the final artifact, just invoke mvn assembly:assembly. If you look in the target folder of your project, you get a zip ready to be deployed in Mule 3. You should also note that the original JAR file of your application is still there…