Creating an Empty Multi-Module Project with Maven and m2eclipse

Why Maven?

Maven is a popular, mature, open source build and project management tool that we’ll be using to manage our Java project.  It provides a lot of different functionality which can be expanded even more through creation of plugins.  Out of the box Maven gives us a few very important things.  First it will handle dependency management for our application that allows us to control dependency version and allows Maven to pull and package them for us.  Secondly it enforces a standard project folder layout that it will copy from when building our artifacts.  M2eclipse gives us the ability to create and manage Maven projects through our Eclipse IDE.

A typical Maven project folder layout looks like this

/src/main/java/each/package/part
/src/main/resources
/src/test/java/each/package/part
/src/test/resources

When we tell Maven to build our project it will compile (if necessary) and copy all the classes and resources under the /src/main folders.  The java folder is intended to hold our java source files.  It follows the convention of having a folder for each part of a packages path so com.mycompany.artifact.MyJavaClass will be stored at /src/main/java/com/mycompany/artifact/MyJavaClass.java on the file system.  At build time Maven will compile and copy java sources along with the folders into our artifacts /classes/ folder.  Maven will also directly copy any thing under /src/main/resources into the /classes/ folder as well.

Test folders follow the same conventions as the main code except that these classes will NOT be packaged in our artifact and instead will just be compiled and run during the build to verify all the code/test cases still pass.  This is an important part in our build process because it allows us to automatically compile and run our test and provide reporting and fail the build if tests fail.

One thing to understand about Maven is that it has an opinionated view on best practices for building and managing projects which a lot of people will cite when comparing it with other build tools that allow for more customization to the build process.  While some will say this is a negative, in reality it enforces a standard layout and allows for people to easily understand the build process of any project since Maven itself enforces its own build conventions.  Using older tools like Ant you can easily customize every stage of the build process to your liking, but this leads to inexperience developers creating large unmanageable build processes and requires that any new team members have to fully sit down and figure out how the build is configured versus just understand how Maven configures its builds.

Finally in the root of each Maven project there will be a POM file.  This is the main configuration file located in the root of all maven projects, including the parent and each module.

Why a Multi-Module Project instead of a standalone?

A single standalone project will contain all our business logic, web tier code, and all resources.  To make management of this code easier Maven allows us to create a hierarchical project tree where we can define standard project settings in our parent project and break out our business code into a separate project than our web tier code.

Lets look at example to understand why mutli-module projects are important.  You have a basic client facing web application that connects to a database and allows the user to update some records from their browser.  Now this project is complete and you decide you want to write another web application facing an internal helpdesk users that shares a lot of the same business code.  In a single module project you now will have to not only pull all the business logic code that you want, but also all the web tier code, which may be completely useless to your new web app or you might just end up copying all your business code into the new project and now need to maintain both sets.  You also have the issue where you need to copy and paste and maintain Maven dependencies and their versions in two project’s POM now instead of just one.

With a multi-module project we can solve the second issue by maintaining all our dependencies and versions in a parent project pom which will be inherited by our child projects.  That way we can continue to add as many child projects as we want and only need to update and maintain dependencies in one place.  We can address the first issue now but breaking our all our business logic into its own project under our Parent.  With our core business logic broken out we can easily declare this project as a dependency in each of the web applications we create.  Now both our internal and external projects will just declare the core business logic project as a dependency and we no longer need to worry about synchronizing changes in business logic across them.  All of this would also apply to having a project that needs a webapp and a batch application and many other cases.

One thing to understand with the Parent project is that it contains no code and does not produce a dependency.  It only provides common configuration across all the child projects and lets Maven know all the projects that are grouped and built together.  In our example case we would end up with two project artifacts, one for the internal and one for the external application, both packaging the core project artifact inside them.

Creating the Project

First thing we need to do is add the Maven Central Archetype catalog to our m2eclipse installation so that we can find the pom-root archetype.  Maven archetypes are just project skeletons that we can use to quickly startup a Maven project instead of creating all the folders ourselves.  In Eclipse open the Windows -> Preferences menu and select the Maven -> Archetypes settings.  Click Add Remote Catalog and enter http://repo1.maven.org/maven2/archetype-catalog.xml for the Catalog File and name it Maven Central.

Next right click the Project Explorer -> Other and select Maven -> Maven Project.  Hit next and when you reach the Select and Archetype menu select Maven Central from the drop down and search for pom-root and select it and hit next.  Finally populate the groupId and artifact name for your maven project and click finish and Maven will generate the Maven folders and a basic parent POM file.

Now that we have a parent Project we can start adding modules.  Again right click the Project Explorer -> Other but this type select Maven -> Maven Module.  Make sure the parent project you created is listed as the parent and give your new module a name.  Typically I name shared code/business logic core and the webapp as webapp with possible a prefix if there’s more than one webapp in the project. Click next and you can select the archetypes for your new modules, which I generally just choose maven-archetype-quickstart which will give you a very basic maven module.  For web projects you can also use the maven-archetype-webapp which will give you the same project layout as the quickstart but also add /webapp/WEB-INF/web.xml folder/file used for Java Servlet Apps and be configured to produce a war artifact.

Once you’ve done the above you should be able to add and launch the application from whichever server you have configured inside eclipse using the WTP, m2e and m2e-wtp plugins.  If you are missing any of the menus above or are unable to deploy your project then you might be missing those plugins.  Previously we setup and configured Eclipse to use WebSphere for our dev environment but the process should be very similar for setting up something like Tomcat or Jboss for those who aren’t required to deploy to the IBM server.

Dependency and Plugin Management

As we said our parent pom holds the configuration for all our plugins and dependencies to be pulled into our modules.  Let’s take a look at a few that we’ll need for most applications.


<dependencyManagement>

<dependencies>
 <dependency>
 <groupId>${project.groupId}</groupId>
 <artifactId>core</artifactId>
 <version>${project.version}</version>
 </dependency>

<dependency>
 <groupId>${project.groupId}</groupId>
 <artifactId>webapp</artifactId>
 <version>${project.version}</version>
 </dependency>
 </dependencies>

</dependencyManagement>

Theses are our child core and webapp modules we created.  The ${project.groupId} is a Maven variable for the projects groupId that we specificed and ${project.version} the projects current version.


<dependencies>
 <dependency>
 <groupId>${project.groupId}</groupId>
 <artifactId>core</artifactId>
 </dependency>

<dependencies>

Here we add the projects core module to the webapp pom so that we can access all the shared business code.


<build>
 <pluginManagement>
 <plugins>
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>${plugin-version.compiler}</version>
 <configuration>
 <source>${build.java.version}</source>
 <target>${build.java.version}</target>
 </configuration>
 </plugin>
 <plugin>
 <artifactId>maven-war-plugin</artifactId>
 <version>${plugin-version.war}</version>
 <configuration>
 <failOnMissingWebXml>false</failOnMissingWebXml>
 </configuration>
 </plugin>
 <plugin>
 <artifactId>maven-jar-plugin</artifactId>
 <version>${plugin-version.jar}</version>
 </plugin>
 <plugin>
 <artifactId>maven-ear-plugin</artifactId>
 <version>${plugin-version.ear}</version>
 </plugin>

</plugins>

</pluginManagement>

</build>

This configures what plugin version we’ll be using for our projects.  We are locking down our war/jar/ear plugin compiler versions here.


<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<build.java.version>1.7</build.java.version>

<plugin-version.compiler>3.1</plugin-version.compiler>

<plugin-version.ear>2.8</plugin-version.ear>
 <plugin-version.jar>2.4</plugin-version.jar>
 <plugin-version.war>2.4</plugin-version.war>
 </properties>

Here we can define replacement properties for use in our pom files using the ${} syntax.  Here we have our plugin version as well as defining our java build version to 1.7 and setting the text sourceEncoding to UTF-8.

Additional Info

We’ve shown how to create a very basic Maven project inside of eclipse, but can achieve the same results using the Maven command line as well. See http://maven.apache.org/guides/getting-started/ for more details.

Also we haven’t gone into the POM, Mavens configuration file, but instead just wanted to go over the very basics of what Maven provides us, and how/why we’d want mult-module projects.  To learn more about Maven and how to configure and use it see http://www.sonatype.com/resources/books for a great set of free ebooks which will cover everything you’d every want to know about using Maven.

Getting a Development Environment Setup with WebSphere 8.5 Liberty Profile and Eclipse 4.2

We’re ramping up a new project at work and we are required to deploy to WebSphere Application Server.  Luckily WebSphere 8.5 seems to be much more lightweight and much easier to use than its predecessors. Everything here will be done on a machine running Windows 7.

We are going to set up a basic development environment with Eclipse to give us Maven integration and WebSphere integration.

Installation

First make sure you have Java JDK 7 or higher installed.   You can check this by running this command


java -version

Next download IBM WebSphere 8.5.5 Liberty Profile. As described on the download page we just need to run the following command and pick a directory to install in.

java -jar wlp-developers-runtime-8.5.5.0.jar

Next download Eclipse 4.2 for JavaEE Developers and extract it into a folder. We are only using 4.2 here instead of the newest 4.3 due to the fact that the IBM WebSphere plugin for Eclipse is only supported up to 4.2. Start up Eclipse and select a workspace and then we’ll need to add a few plugins.

First we’ll need the IBM WebSphere 8.5.5 Developer Tools for Eclipse. You can install this by either searching the Help -> Eclipse Market Place or dragging the install button into the Eclipse from the IBM WebSphere 8.5.5 Liberty Profile download page. Install the plugins, accept any notifications and then Eclipse will restart.

In the Eclipse Server tab (ctrl+3 and search for server if you cannot find it) click the No Servers Available. Define a new server from the new server wizard.. link.  This will open the New Server dialog where you can select the the WebSphere Application Server V8.5 Liberty Profile  server under the IBM folder. If you don’t see the IBM folder or the server than you need to make sure you installed the necessary Eclipse plugin in the previous step.

Hit next and you’ll see the Liberty Profile Runtime Environment dialog. Browser to the folder where you installed WebSphere above and leave the default jre (which should be jre7 if you have the newest java correctly installed).  Click next and rename the server if you want. Note the info for the default HTTP End point and hit finish.

The server window should now have your new server, right click it and select start.  The server should now start up, you can see the debug information in the Console window. Open a web browser and navigate to http://localhost:9080 (or whatever you changed the end point too) and you should see the some information and link to other WebSphere resources.

Next we’ll want to installed the m2e-wtp plugin which will add Maven support the to Eclipse WTP Plugin.  Go to the Eclipse Market Place and search for m2e-wtp and select Maven Integration for Eclipse WTP (Juno) and let Eclipse restart after installing.

Create a Maven Project and Deploy to WebSphere

m2e-wtp installs the m2eclipse plugin which gives us a simple way to create new maven projects.  Right click your project tab and select New -> Other and under Maven select New Maven Project. Pick where you want the project created, select maven-archtype-webapp on the next screen and finally enter the groupId and artifactId for the project.

m2e will now create a very basic webapp project for you. In the server tab right click the WebSphere server and click Add and Remove… and then you should see the newly create project in the Available side, highlight your project and click the Add button to configure the project for the server.

Right click your server again and hit start.  Navigate to http://localhost:9080/appname where appname is what you see under the WebSphere server in Eclipse.  If you were successful with everything you should see a simple page that says “Hello World!”