How do I create a multi-module project in Eclipse?
Author: Deron Eriksson
Description: This tutorial describes how to create a multi-module maven project in Eclipse.
Tutorial created using: Windows Vista || JDK 1.6.0_04 || Eclipse Web Tools Platform 2.0.1 (Eclipse 3.3.1)


Page: < 1 2

(Continued from page 1)

Now that we have a multi-module project called "myproject" with the modules "mytest" and "mytest2", let's see an example of some of the multi-module capabilities of mavenSW. Let's start by performing a "mvn clean package" on "myproject" and see what happens.

Executing 'mvn clean package' on 'myproject'

The console output of "mvn clean package" on "myproject" is shown here. Notice that both the "mytest" and "mytest2" projects get cleaned and built as a result of this single command! Using a multi-module project, I've built over 40 related modules before, all with just a click of a button!

Console output of 'mvn clean package' on 'myproject'

[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   myproject
[INFO]   mytest
[INFO]   mytest2
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] [site:attach-descriptor]
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory C:\dev\workspace\mytest\target
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 2 source files to C:\dev\workspace\mytest\target\classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to C:\dev\workspace\mytest\target\test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: C:\dev\workspace\mytest\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.maventest.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.037 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar: C:\dev\workspace\mytest\target\mytest-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest2
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory C:\dev\workspace\mytest2\target
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 2 source files to C:\dev\workspace\mytest2\target\classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to C:\dev\workspace\mytest2\target\test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: C:\dev\workspace\mytest2\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.maventest.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.037 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar: C:\dev\workspace\mytest2\target\mytest2-1.0-SNAPSHOT.jar
[INFO] 
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] myproject ............................................. SUCCESS [2.412s]
[INFO] mytest ................................................ SUCCESS [2.903s]
[INFO] mytest2 ............................................... SUCCESS [1.564s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 seconds
[INFO] Finished at: Tue Feb 12 17:57:49 PST 2008
[INFO] Final Memory: 18M/32M
[INFO] ------------------------------------------------------------------------

Now, let's see another example of one of the really cool things that we can do with a multi-module project in EclipseSW using the maven eclipseSW plugin. I'll perform a "mvn eclipse:eclipse" on "myproject".

Executing 'mvn eclipse:eclipse' on 'myproject'

The console output of "mvn eclipse:eclipse" on "myproject" is shown below. The "eclipse:eclipse" goal is performed on "myproject", "mytest", and "mytest2".

Console output of 'mvn eclipse:eclipse' on 'myproject'

[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   myproject
[INFO]   mytest
[INFO]   mytest2
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse]
[INFO] Not running eclipse plugin goal for pom project
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse]
[INFO] Using source status cache: C:\dev\workspace\myproject\target\mvn-eclipse-cache.properties
[INFO] Not writing settings - defaults suffice
[INFO] File C:\dev\workspace\mytest\.project already exists.
       Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed.
[INFO] Wrote Eclipse project for "mytest" to C:\dev\workspace\mytest.
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest2
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse]
[INFO] Using source status cache: C:\dev\workspace\myproject\target\mvn-eclipse-cache.properties
[INFO] Not writing settings - defaults suffice
[INFO] File C:\dev\workspace\mytest2\.project already exists.
       Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed.
[INFO] Wrote Eclipse project for "mytest2" to C:\dev\workspace\mytest2.
[INFO] 
[INFO] 
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] myproject ............................................. SUCCESS [0.909s]
[INFO] mytest ................................................ SUCCESS [0.075s]
[INFO] mytest2 ............................................... SUCCESS [0.034s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Tue Feb 12 17:58:59 PST 2008
[INFO] Final Memory: 3M/7M
[INFO] ------------------------------------------------------------------------

Now, let's look at the .classpath file of "mytest". Notice that the "eclipse:eclipse" goal updated the .classpath to contain the commons-lang jarW file, which makes sense since it is listed as a dependency in the "mytest" pom.xml file. Notice that the junit dependency has been included in the classpathW since the "mytest" project gets this through inheritance from "myproject".

.classpath file of 'mytest'

<classpath>
  <classpathentry kind="src" path="src/main/java"/>
  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
  <classpathentry kind="output" path="target/classes"/>
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
  <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.3/commons-lang-2.3.jar"/>
  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
</classpath>

If we inspect the .classpath file of "mytest2", we'll see something very cool. First, notice that the commons-lang and junit jars are present, which is to be expected. It gets the junit dependency through inheritance from "myproject", and it gets the commons-lang dependency as a transitive dependency from "mytest", since "mytest2" depends on "mytest". However, notice that the .classpath also contains a source reference to "/mytest"! The "mytest" project is included in the build path of "mytest2" as a result of executing the "eclipse:eclipse" goal on "myproject". This makes it possible to debug across related projects, which can be extremely handy in large applications that include multiple modules.

.classpath file of 'mytest2'

<classpath>
  <classpathentry kind="src" path="src/main/java"/>
  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
  <classpathentry kind="output" path="target/classes"/>
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
  <classpathentry kind="src" path="/mytest"/>
  <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.3/commons-lang-2.3.jar"/>
  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
</classpath>
Page: < 1 2