Maven is a Java project’s build system. I have seen other attempts to create an all encompassing system, and really had not used Maven, not really seeing a big difference between it and Ant. Until a project I started on six months ago that used Maven, that’s when I learned the real power behind Maven and it’s great features. Now I had done some Continuous Integration work before, those were usually a mashup of various build systems, and customized scripting. Development teams had patched together various systems. I just received the builds from the systems and had to have code that tested and deployed these builds out to various systems. Not an ideal situation. Any kind of consistent build system Ant, Maven, makefiles, or anything else would have been a much better situation, however that was a luxury I didn’t have.
Now about six months ago I started on a new project that was already based on Maven. It consisted of four project object model (POM) files one parent and 3 children. Two of the children build EARs for their components and the third packaged them together as a WAR file. Being able to add a few lines to the POM file to include in another library we needed to use really started showing me how nice Maven was. Packaging up the 3rd Party libraries into the EARs really saved a significant amount of work. The final straw that completely sold me on the power and flexibility of Maven is when I had to remove a library. Well it completely broke the build, at first I was not happy. The code was no longer compiling not because of the library I removed, but because of the dependencies that were not gone. I came to realize, prior to me starting this project, code had been developed without every looking to verify how we were picking up the required libraries.
At first I was concerned this was going to be a long process sorting out what I needed to include. Instead it turned into a simple process once I found the Maven Repository. A few searches and I found what I needed, then a few compile attempts and everything was back to being happy. The end result was our WAR file was significantly smaller because I discovered a number of libraries we needed were really provided and didn’t need to be bundled. That day I became a true Maven Convert.
Today I’m going to share some basic’s I learned with you.
This is what gives Maven it’s real power. You need to understand Maven Plugins, before Archetypes. A Maven Plugin, provides very specific functionality. This could be anything. Some examples are:
- maven-assembly-plugin – Assemble the generated code, and resource files into a ZIP, JAR, EAR, WAR or ….. This includes packing the Dependencies required to be shipped as well.
- jandex-maven-plugin – Create an Index of Annotations on the generated code
- maven-javadoc-plugin – Generate the JavaDoc from your source, and package it into a JAR file for JavaDoc. Now this had me confused as I kept looking for my JavaDoc in my main JAR file.
- jaxb2-maven-plugin – Generate Java files from an XSD.
- maven-compiler-plugin – Configuration and control of your Java compilation.
There are probably hundreds of plugins for Maven. These are just a few.
These are very important and your starting point for creating a new Maven project. Archetypes are essentially a beginning block for your POM file. Now you may ask exactly what does an archetype do? Well it creates your pom.xml file we some sample/default settings. It includes various Maven Plugins that provide the functionality, and the configuration for these plugins for this kind of project. Here are few of the more common Archetypes:
- maven-archetype-j2ee-simple – Create a simple J2EE project. This is for building, packaging and deploying a J2EE project.
- maven-archetype-quickstart – Generates a simple project for building a JAR file, and running tests.
- maven-archetype-webapp – Generates a project for a Web App.
Archetypes are completely extensible, so anyone can add/create new Archetypes.
You specify the Group ID, Artifact ID and the Version to add a dependency to a project. You can look these up on the Maven Repository. Find the library and version you need then add it to the POM file. Here is an example:
<dependency> <groupId>org.jboss</groupId> <artifactId>jandex</artifactId> <version>2.0.3.Final</version> </dependency>
You can also add a scope, which tells the build when it needs to use this dependency:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
Scopes can be created. Here are the basic ones that are available:
- compile – Default scope. This dependency will be available to ALL classpaths used in the build. If the maven-assembly-plugin is used it will include this dependency in the file artifact.
- provided – Used in call classpaths for building, and testing. Will not be packaged, as it indicates the library will be available to the system at runtime.
- runtime – Dependency is not required for compilation, but is for execution. It will be for the runtime and test classpaths
- test – Dependency is only required for the test classpath. Will not be present on any other classpath.
- system – Similar to “provided” except the dependency is not automatically loaded, instead a JAR file that contains it explicitly provided.
Maven provides a build system that can be easily extended, with a define directory structure it allows for less configuration that previous attempts, while still maintaining a great deal of flexibility. Please watch as I add further information on Maven and usage in the future.