Saturday, November 3, 2012

How to create multi module project with maven?

It is more than three years, I have started to use maven and it is a great tool, I have ever used. The support of repository management and the features available to create multi module project are excellent. With this tutorial, I am going to show you, how to create a multi module project with maven. I am using eclipse as IDE and 'm2eclipse' plugin for eclipse.

The following picture shows the project structure in eclipse.

My project is 'shims' and it has two modules as 'shims-core' and 'shims-web'. One module contains all business logic classes and data access objects which is bundled as jar file. And the other module is the web module which contains controller related classes (Struts2 action or Servlets or Spring controller classes) and view related stuff.

The tutorial summary is as follows.
Installing maven

Download the Apache maven distribution and extract it some where in your computer. You can download the apache maven from here. I have extracted the distribution into the following location in my computer.

/home/vinesh/apache-maven-3.0.4

Next, You have to set 'MAVEN_HOME' environmental variable and add the path of maven's bin folder to classpath. In Ubuntu, you can set the variable as follows. You have to add the following two lines into bashrc file. First, run the following command to open 'bashrc' file.

$ vi ~/.bashrc

And add the following two lines.

export MAVEN_HOME=/home/vinesh/apache-maven-3.0.4
export PATH=$MAVEN_HOME/bin:$PATH

In windows, setting an environment variable is not that much difficult. So I am not going to explain that in this tutorial.

After editing 'bashrc' file, just open a command window and run the following command.

$ mvn -version

If you get the output similar to following, you are successfully configured apache maven.

Apache Maven 3.0.4 (r1232337; 2012-01-17 14:14:56+0530)
Maven home: /home/semika/apache-maven-3.0.4
Java version: 1.6.0_30, vendor: Sun Microsystems Inc.
Java home: /home/semika/java/jdk1.6.0_30/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "2.6.38-16-generic", arch: "amd64", family: "unix"

You are done with the first step and let's move to next step.  

Configure m2eclipse, maven with eclipse 

You have to install m2eclipse plugin first. You can install m2eclipse plugin via eclipse it self. I am using eclipse 'Indigo' version and there may be slight differences with other version of eclipse. 

This is the update URL for m2eclipse.

http://download.eclipse.org/technology/m2e/releases

Go to Help --> Install New Software. You will get the following window.



You can add the above update URL and continue the wizard. Normally this will take some time and after finishing the installation, you have to restart the eclipse. Go to Window -->Preferences. You should see that 'Maven' category has added to preferences categories.


We are not going to use embedded maven coming with the plugin as I have highlighted in the above image. Instead, we are going to configure our maven installation with eclipse. 

Click the 'Add' button and locate your maven installation directory. For further clarification see the image bellow. 


You can see now, the plugin has been configured with our maven installation. Now, you are ready to create projects using m2eclipse. Let's start to create our multi module project.

Eclipse provides great facilities to create multi module projects and relationships among the modules. In this tutorial, I am going to create a maven multi module projects from the scratch.




 
Creating maven parent project

Step01: Go to File --> New --> Project.

You will get 'New Project' window. Under 'Maven' category, select 'Maven Project'. Click 'Next' button. You will get 'New Maven Project' window. See the bellow image.



Step 02: We are going to create simple maven project. As I have pointed out from right side image, make sure to check 'Create a simple project' checkbox. Click on 'Next' button. Then you will get the following window.

I feel, it is better to give little explanation about the four fields highlighted with red color box in the right side image.

Group Id: This is the root packaging structure of your project. Make sure to use the same root package structure for every module in the project. 

Artifact Id : This is similar to your project module name. In right side image, I have given 'shims' as the artifact id. That is the parent project of my all project modules.

Packaging: This is very important when creating multi module project with maven. There are several options which you can select as the packaging. If you want to create a parent project, we are doing like now, you have to select 'pom' as the packaging. To create Java module, select 'jar' and for web module, select 'war'. I will explain later on this tutorial, how to create a 'jar' and 'war' module. You know that 'shims-core' is a jar module which contains all the business logic and data access objects and 'shims-web' is a web module containing all controller  and view related stuff.

Click the 'Finish' button and see, maven is creating the parent project for our multi module project. Let's little examine this.

Open the 'pom.xml' file. It should be similar to the following.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.semika</groupId>
  <artifactId>shims</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
</project>


Let's create our first child module.  

Creating maven child jar module

We want to keep our all business logic and DAO classes as a separate module which can be bundled to as a 'jar' file. We can create a separate project module for this purpose. In my sample application, it has 'shims-core' module. This is a child module of our parent project which we already created. 

To create child jar module.

Step 01: Right click on the parent project, Go to New-->Project. Select the 'Maven Module' from the 'Maven' category. As you can remember, we selected 'Maven Project' when we create our parent project before. Since we are creating a project module now, we should select 'Maven Module'. 

Click the 'Next' button. You will get 'New Maven Module' window as follows.



Make sure to check 'Create a simple project' check box and give a module name. You can see that 'shims' which is our parent project has automatically selected as the 'Parent Project'. We are in a correct way. Click the 'Next' button. You will get familiar window as follows.


As You can see in the right side image, 'Group Id', 'Artifact Id' and 'Version' have already been set by default. We don't need to change any of those three field values. Keep those values as it is. Since we are creating 'jar' module, we should select 'jar' as the packaging. Click the 'Finish' button and see maven is creating our first child module.

Now refresh the parent project and notice that maven has created a new project 'shims-core' inside the 'shims'. The 'shims-core' represents a another maven project module which has separate pom.xml file. Also 'shims-core' represents as the new project within eclipse.

Just have a look on following image.

Now, If you see parent project's pom.xml file, you can see that 'shims-core' has listed under modules which says that 'shims-core' is a child module of 'shims' parent project.

  <modules>
   <module>shims-core</module>
  </modules>

Also, in the child project's pom.xml file, it has a reference to parent project. Further, in child module's pom.xml file, 'groupId' and 'version' have not been defined. Those are inherited from parents project. This is good practice when you are creating multi module project with maven.
  <parent>
    <artifactId>shims</artifactId>
    <groupId>com.semika</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>..</relativePath>
  </parent>


Creating child war module

Next, we will create our web module, 'shims-web' which contains our controller classes and other view related stuff. Creating war module with m2eclipse is little different rather creating jar module. We have to use one of the maven pre-defined archetype  for web module creation. Don't worry, I will give you step by step explanation about creating maven war module. 

Step 01: Right click on parent project, Go to New-->Project and select 'Maven Module', Click 'Next' button.

In this case, we are not going to create a simple project. So don't check on 'Create simple project' check box. As you can see from the right side image, parent project has automatically selected as 'shims' which is our parent project. You have to specify the module name as 'shims-web'. and click 'Next' button.




Step 02: Click the 'Next' button from the above image. We are going to use 'maven-archetype-webapp' artifact to create our war module. See the bellow image.


Step 03: Click 'Next'  button from above window and you will get the following window.


You only need to change the 'Package' from right side window. Click the 'Finish' button and let the maven create our web module. After creating the new web module, refresh the parent project and notice that it has a new module as 'shims-web'. So now we have a multi module project with tow modules. Open pom.xml file from the web module and make sure to remove 'groupId' and 'version'. Also see the parent project's pom.xml file and notice that 'shims-web' has been added to it as a new module.

We hope to deploy our application as a war bundle into the server. If you want to change you war file name, you can change 'filaName' attribute of pom.xml file of 'shims-web' module.


  <build>
    <finalName>shims-web</finalName>
  </build>

This will create 'shims-web.war' file under 'target' directory of 'shims-web' module. Next, we need to define dependencies between 'shims-core' and 'shims-web' module. This will force the maven reactor to build 'shims-core' module before building 'shims-web' module when we run maven build from the parent project. Because, we want to bundle our business logic and DAO related classes into a separate jar module and give it to web module as a separate library along with other libraries, core module should be build before web module.

Place the following contents inside the 'dependencies' section of pom.xml file of 'shims-web' module.

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

${project.groupId} and ${project.version} are two global references of maven which provides 'groupId' and 'version' across the whole modules of the multi module project. We can directly use it.

Building multi module project

There are lots of advantages of creating multi module project. We can build the entire project at once and also we can build each module separately. Developers can separately work on different modules at the same time without depending on others. Other thing is, we have clear separation which enhance maintainability.
We have to create maven targets to build our project. Right click on parent project. Go to Run As --> Maven Build. You will get the following window only for the very first time. There you can create a new target to build your project. 
The right side window allow you to create maven target to build your project. You have to give a name for your build target and browse the required project module directory. Since I am going to create this maven target to build the entire project, I have located my parent directory. Put 'clean install' into the Goals field.
Since, we are going to build our project very first time, we should allow maven to download the required dependencies from their global repository. Make sure 'offline' check box 'unchecked'. After first success build, you can update this target to run it in offline mode by selecting 'offline' check box.
Make sure 'Maven Runtime' has been set to our maven installation directory. Otherwise you will get build errors.

OK!. That's it. You are ready to build your first maven multi module project. Good luck!

Click on 'Apply' and then 'Run' button. Maven will start the building project. See carefully eclipse console. It says full story. You should get 'SUCCESS' message at the end of the build. Similar output as follows.

-------------------------------------
[INFO] Installing /home/vinesh/workspace-maaven/shims/shims-web/pom.xml to /home/vinesh/.m2/repository/com/semika/shims-web/1.0-SNAPSHOT/shims-web-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] [INFO] shims ............................................. SUCCESS [1.093s]
[INFO] shims-core ........................................ SUCCESS [2.005s]
[INFO] shims-web Maven Webapp ............................ SUCCESS [1.027s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.354s
[INFO] Finished at: Sat Nov 03 22:37:27 IST 2012
[INFO] Final Memory: 6M/103M
[INFO] ------------------------------------------------------------------------

Let's deploy our application. I am using Apache tomcat7 to deploy my application. If you see inside the target directory of 'shims-web' module after the successful build, you can see,maven has create 'shims-web.war' file. Copy that file into tomcat's webapps folder and start the tomcat.

Point your browser the following URL.

http://localhost:8080/shims-web/

You should get hello world page. 


You may also like:

9 comments:

  1. thanks, your post help me very much

    ReplyDelete
  2. very fine and excellent article

    ReplyDelete
  3. Very good article . keep posting

    ReplyDelete
  4. really is very good tuto, big thanks for this :)

    ReplyDelete
  5. Good Post, Exactly what I was looking for... Thanks, Keep it up !

    ReplyDelete
  6. Excellent post, please let us know, how to deploy the web application from Maven using Eclipse IDE.

    ReplyDelete

Share

Widgets