Creating a multi-module application

duration 30 minutes
Git clone to get going right away:
git clone https://github.com/OpenLiberty/guide-maven-multimodules.git
Copy Github clone command

You will learn how to build an application with multiple modules with Maven and Open Liberty.

What you’ll learn

A Java Platform, Enterprise Edition (Java EE) application consists of modules that work together as one entity. An enterprise archive (EAR) is a wrapper for a Java EE application, which consists of web archive (WAR) and Java archive (JAR) files. Package modules and resources into an EAR file to deploy or distribute the Java EE application to new environments.

You will learn how to establish a dependency between a web module and a Java library module. Next, use Maven to package the WAR file and the JAR file into an EAR file so that you can run and test the application on Open Liberty.

You will build a unit converter application that converts heights from centimeters into feet and inches. Enter heights in centimeters from a web page, and the application processes the input with functions in the JAR file to return the corresponding height in Imperial units.

Getting started

The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:

git clone https://github.com/openliberty/guide-maven-multimodules.git
cd guide-maven-multimodules

The start directory contains the starting project that you will build upon.

The finish directory contains the finished project that you will build.

Access partial implementation of the application from the start folder. This folder includes a web module in the war folder, a Java library in the jar folder, and template files in the ear folder. However, the Java library and the web module are independent projects, and you will need to complete the following steps to implement the application:

  1. Add a dependency relationship between two modules.

  2. Assemble the entire application into an EAR file.

  3. Aggregate the entire build.

  4. Test the multi-module application.

Adding dependencies between WAR and JAR modules

To use the Java library in your web module, add a dependency relationship between them.

As you might notice, each module has its own pom.xml file because each module is treated as an independent project. You can rebuild, reuse, and reassemble every module on its own.

Navigate to the start directory to begin.

Replace the war/POM file.
war/pom.xml

war/pom.xml

 1<?xml version='1.0' encoding='utf-8'?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0"
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4         xsi:schemaLocation=
 5         "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 6  <modelVersion>4.0.0</modelVersion>
 7  <groupId>io.openliberty.guides</groupId>
 8  <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 9  <packaging>war</packaging>
10  <version>0.0.1-SNAPSHOT</version>
11  <name>io.openliberty.guides.multimodules.war</name>
12  <url>http://maven.apache.org</url>
13
14
15  <dependencies>
16    <dependency>
17      <groupId>junit</groupId>
18      <artifactId>junit</artifactId>
19      <version>4.12</version>
20      <scope>test</scope>
21    </dependency>
22
23    <dependency>
24      <groupId>javax.servlet</groupId>
25      <artifactId>javax.servlet-api</artifactId>
26      <version>3.1.0</version>
27      <scope>provided</scope>
28    </dependency>
29
30    <dependency>
31      <groupId>io.openliberty.guides</groupId>
32      <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
33      <version>0.0.1-SNAPSHOT</version>
34    </dependency>
35  </dependencies>
36
37</project>

The <dependency/> element is the Java library module that implements the functions that you need for the unit converter.

With this dependency, you can use any functions included in the library in the HeightsBean.java file of the web module.

Replace the HeightsBean class.
war/src/main/java/io/openliberty/guides/multimodules/web/HeightsBean.java

HeightsBean.java

 1package io.openliberty.guides.multimodules.web;
 2
 3public class HeightsBean implements java.io.Serializable {
 4  private String heightCm = null;
 5  private String heightFeet = null;
 6  private String heightInches = null;
 7  private int cm = 0;
 8  private int feet = 0;
 9  private int inches = 0;
10
11  public HeightsBean() {
12  }
13
14  // Capitalize the first letter of the name i.e. first letter after get
15  // If first letter is not capitalized, it must match the property name in index.jsp
16  public String getHeightCm() {
17    return heightCm;
18  }
19
20  public String getHeightFeet() {
21    return heightFeet;
22  }
23
24  public String getHeightInches() {
25    return heightInches;
26  }
27
28  public void setHeightCm(String heightcm) {
29    this.heightCm = heightcm;
30  }
31
32  // Need an input as placeholder, you can choose not to use the input
33  public void setHeightFeet(String heightfeet) {
34    this.cm = Integer.valueOf(heightCm);
35    this.feet = io.openliberty.guides.multimodules.lib.Converter.getFeet(cm);
36    String result = String.valueOf(feet);
37    this.heightFeet = result;
38  }
39
40  public void setHeightInches(String heightinches) {
41    this.cm = Integer.valueOf(heightCm);
42    this.inches = io.openliberty.guides.multimodules.lib.Converter.getInches(cm);
43    String result = String.valueOf(inches);
44    this.heightInches = result;
45  }
46
47}

The getFeet(cm) was added to the setHeightFeet method to convert a measurement into feet.

The getInches(cm) was added to the setHeightInches method to convert a measurement into inches.

Assembling multiple modules into an EAR file

To deploy the entire application on the Open Liberty server, first package the application. Use the EAR project to assemble multiple modules into an EAR file.

Navigate to the ear folder and find a template pom.xml file.

Replace the ear/POM file.
ear/pom.xml

ear/pom.xml

  1<?xml version='1.0' encoding='utf-8'?>
  2<project xmlns="http://maven.apache.org/POM/4.0.0"
  3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4         xsi:schemaLocation=
  5         "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6
  7  <modelVersion>4.0.0</modelVersion>
  8  <groupId>io.openliberty.guides</groupId>
  9  <artifactId>io.openliberty.guides.multimodules.ear</artifactId>
 10  <version>0.0.1-SNAPSHOT</version>
 11  <packaging>ear</packaging>
 12
 13
 14  <dependencies>
 15    <!-- web and jar modules as dependencies -->
 16    <dependency>
 17      <groupId>io.openliberty.guides</groupId>
 18      <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 19      <version>0.0.1-SNAPSHOT</version>
 20      <type>jar</type>
 21    </dependency>
 22    <dependency>
 23      <groupId>io.openliberty.guides</groupId>
 24      <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 25      <version>0.0.1-SNAPSHOT</version>
 26      <type>war</type>
 27    </dependency>
 28    <dependency>
 29      <groupId>junit</groupId>
 30      <artifactId>junit</artifactId>
 31      <version>4.12</version>
 32      <scope>test</scope>
 33    </dependency>
 34  </dependencies>
 35
 36  <build>
 37    <plugins>
 38      <plugin>
 39        <groupId>org.apache.maven.plugins</groupId>
 40        <artifactId>maven-ear-plugin</artifactId>
 41        <version>3.0.1</version>
 42        <configuration>
 43          <modules>
 44            <jarModule>
 45              <groupId>io.openliberty.guides</groupId>
 46              <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 47              <uri>/io.openliberty.guides.multimodules.jar-0.0.1-SNAPSHOT.jar</uri>
 48            </jarModule>
 49            <webModule>
 50              <groupId>io.openliberty.guides</groupId>
 51              <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 52              <uri>/io.openliberty.guides.multimodules.war-0.0.1-SNAPSHOT.war</uri>
 53              <!-- Set custom context root -->
 54              <contextRoot>/converter</contextRoot>
 55            </webModule>
 56          </modules>
 57        </configuration>
 58      </plugin>
 59
 60      <!-- Enable liberty-maven plugin -->
 61      <plugin>
 62        <groupId>net.wasdev.wlp.maven.plugins</groupId>
 63        <artifactId>liberty-maven-plugin</artifactId>
 64        <configuration>
 65          <assemblyArtifact>
 66            <groupId>io.openliberty</groupId>
 67            <artifactId>openliberty-runtime</artifactId>
 68            <version>RELEASE</version>
 69            <type>zip</type>
 70          </assemblyArtifact>
 71          <configFile>src/main/liberty/config/server.xml</configFile>
 72          <packageFile>${package.file}</packageFile>
 73          <include>${packaging.type}</include>
 74          <bootstrapProperties>
 75            <default.http.port>${testServerHttpPort}</default.http.port>
 76            <default.https.port>${testServerHttpsPort}</default.https.port>
 77          </bootstrapProperties>
 78        </configuration>
 79        <executions>
 80          <!-- Copy ear to defaultServer/apps -->
 81          <execution>
 82            <id>install-apps</id>
 83            <configuration>
 84              <looseApplication>true</looseApplication>
 85              <stripVersion>false</stripVersion>
 86              <installAppPackages>project</installAppPackages>
 87            </configuration>
 88          </execution>
 89        </executions>
 90      </plugin>
 91
 92      <!-- Since the package type is ear, need to run testCompile to compile the tests -->
 93      <plugin>
 94        <groupId>org.apache.maven.plugins</groupId>
 95        <artifactId>maven-compiler-plugin</artifactId>
 96        <version>3.7.0</version>
 97        <executions>
 98          <execution>
 99            <phase>test-compile</phase>
100            <goals>
101              <goal>testCompile</goal>
102            </goals>
103          </execution>
104        </executions>
105      </plugin>
106
107      <!-- Plugin to run integration tests -->
108      <plugin>
109        <groupId>org.apache.maven.plugins</groupId>
110        <artifactId>maven-failsafe-plugin</artifactId>
111        <version>3.0.0-M1</version>
112        <executions>
113          <execution>
114            <phase>integration-test</phase>
115            <id>integration-test</id>
116            <goals>
117              <goal>integration-test</goal>
118            </goals>
119            <configuration>
120              <includes>
121                <include>**/it/**</include>
122              </includes>
123              <systemPropertyVariables>
124                <liberty.test.port>${testServerHttpPort}</liberty.test.port>
125                <running.bluemix>${running.bluemix}</running.bluemix>
126                <cf.context.root>${cf.context.root}</cf.context.root>
127              </systemPropertyVariables>
128            </configuration>
129          </execution>
130          <execution>
131            <id>verify-results</id>
132            <goals>
133              <goal>verify</goal>
134            </goals>
135          </execution>
136        </executions>
137        <configuration>
138          <summaryFile>${project.build.directory}/test-reports/it/failsafe-summary.xml</summaryFile>
139          <reportsDirectory>${project.build.directory}/test-reports/it</reportsDirectory>
140        </configuration>
141      </plugin>
142    </plugins>
143  </build>
144
145</project>

Set the basic configuration for the project and set the <packaging/> element to ear.

The Java library module and the web module were added as dependencies. Specify <type>war</type> for the web module. If you don’t specify the web module, Maven looks for a JAR file.

The definition and configuration of the maven-ear-plugin plug-in were added to create an EAR file. Define the <jarModule/> and <webModule/> modules to be packaged into the EAR file. To customize the context root of the application, set the appropriate contextRoot in the webModule. Otherwise, Maven automatically uses the WAR file artifactId ID as the context root for the application while generating the application.xml file.

To download and start an Open Liberty server, use the liberty-maven-plugin plug-in for Maven. This configuration is provided, and the executions of the plug-in follow the typical phases of a Maven life cycle.

To deploy the EAR application, you need to congiure a server.

Create the server configuration file.
ear/src/main/liberty/config/server.xml

server.xml

 1<server description="Sample Liberty server">
 2
 3  <!-- Enable features -->
 4  <featureManager>
 5    <feature>jsp-2.3</feature>
 6  </featureManager>
 7
 8  <!-- To access this server from a remote client add a host attribute to the following
 9    element, e.g. host="*" -->
10  <httpEndpoint host="*" httpPort="${default.http.port}" httpsPort="${default.https.port}"
11    id="defaultHttpEndpoint" />
12
13  <enterpriseApplication id="io.openliberty.guides.multimodules.ear"
14    location="io.openliberty.guides.multimodules.ear-0.0.1-SNAPSHOT.ear"
15    name="io.openliberty.guides.multimodules.ear" />
16</server>

Aggregating the entire build

Because you have multiple modules, aggregate the Maven projects to simplify the build process.

Create a parent pom.xml file under the start directory to link all of the child modules together. A template is provided for you.

Replace the start/POM file.
pom.xml

start/pom.xml

 1<?xml version='1.0' encoding='utf-8'?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0"
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4         xsi:schemaLocation=
 5         "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 6
 7    <parent>
 8        <groupId>net.wasdev.wlp.maven.parent</groupId>
 9        <artifactId>liberty-maven-app-parent</artifactId>
10        <version>RELEASE</version>
11    </parent>
12
13    <modelVersion>4.0.0</modelVersion>
14    <groupId>io.openliberty.guides</groupId>
15    <artifactId>io.openliberty.guides.multimodules.modules</artifactId>
16    <version>0.0.1-SNAPSHOT</version>
17    <packaging>pom</packaging>
18
19    <modules>
20        <module>jar</module>
21        <module>war</module>
22        <module>ear</module>
23    </modules>
24
25    <properties>
26        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
27        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
28        <maven.compiler.source>1.8</maven.compiler.source>
29        <maven.compiler.target>1.8</maven.compiler.target>
30        <app.name>LibertyProject</app.name>
31        <testServerHttpPort>9080</testServerHttpPort>
32        <testServerHttpsPort>9443</testServerHttpsPort>
33        <package.file>${project.build.directory}/${app.name}.zip</package.file>
34        <packaging.type>usr</packaging.type>
35    </properties>
36
37    <dependencies>
38        <!-- Support for JDK 9 and above -->
39        <dependency>
40            <groupId>javax.xml.bind</groupId>
41            <artifactId>jaxb-api</artifactId>
42            <version>2.3.1</version>
43        </dependency>
44        <dependency>
45            <groupId>com.sun.xml.bind</groupId>
46            <artifactId>jaxb-core</artifactId>
47            <version>2.3.0.1</version>
48        </dependency>
49        <dependency>
50            <groupId>com.sun.xml.bind</groupId>
51            <artifactId>jaxb-impl</artifactId>
52            <version>2.3.2</version>
53        </dependency>
54        <dependency>
55            <groupId>javax.activation</groupId>
56            <artifactId>activation</artifactId>
57            <version>1.1.1</version>
58        </dependency>
59    </dependencies>
60</project>

Set the basic configuration for the project. Set pom as the <packaging/> element of the parent pom.xml file. Specify io.openliberty.guides as the <groupId/> ID, which the child pom.xml files will inherit.

In the parent pom.xml file, list all of the <modules/> that you want to aggregate for the application.

Lastly,

Update the pom.xml in the child module jar, war and ear projects.
jar/pom.xml
war/pom.xml
ear/pom.xml

Add a <parent/> section just above basic configuration to each of the pom.xml files in the child modules, such as the jar, war, and ear projects.

pom.xml

1  <parent>
2    <groupId>io.openliberty.guides</groupId>
3    <artifactId>io.openliberty.guides.multimodules.modules</artifactId>
4    <version>0.0.1-SNAPSHOT</version>
5  </parent>

jar/pom.xml

 1<?xml version='1.0' encoding='utf-8'?>
 2<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">
 3
 4  <modelVersion>4.0.0</modelVersion>
 5  <groupId>io.openliberty.guides</groupId>
 6  <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 7  <version>0.0.1-SNAPSHOT</version>
 8
 9  <parent>
10    <groupId>io.openliberty.guides</groupId>
11    <artifactId>io.openliberty.guides.multimodules.modules</artifactId>
12    <version>0.0.1-SNAPSHOT</version>
13  </parent>
14
15</project>

war/pom.xml

 1<?xml version='1.0' encoding='utf-8'?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0"
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4         xsi:schemaLocation=
 5         "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 6  <modelVersion>4.0.0</modelVersion>
 7  <groupId>io.openliberty.guides</groupId>
 8  <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 9  <packaging>war</packaging>
10  <version>0.0.1-SNAPSHOT</version>
11  <name>io.openliberty.guides.multimodules.war</name>
12  <url>http://maven.apache.org</url>
13
14  <parent>
15    <groupId>io.openliberty.guides</groupId>
16    <artifactId>io.openliberty.guides.multimodules.modules</artifactId>
17    <version>0.0.1-SNAPSHOT</version>
18    <relativePath>../pom.xml</relativePath>
19  </parent>
20
21  <dependencies>
22    <dependency>
23      <groupId>junit</groupId>
24      <artifactId>junit</artifactId>
25      <version>4.12</version>
26      <scope>test</scope>
27    </dependency>
28
29    <dependency>
30      <groupId>javax.servlet</groupId>
31      <artifactId>javax.servlet-api</artifactId>
32      <version>3.1.0</version>
33      <scope>provided</scope>
34    </dependency>
35
36    <dependency>
37      <groupId>io.openliberty.guides</groupId>
38      <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
39      <version>0.0.1-SNAPSHOT</version>
40    </dependency>
41  </dependencies>
42
43</project>

ear/pom.xml

  1<?xml version='1.0' encoding='utf-8'?>
  2<project xmlns="http://maven.apache.org/POM/4.0.0"
  3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4         xsi:schemaLocation=
  5         "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6
  7  <modelVersion>4.0.0</modelVersion>
  8  <groupId>io.openliberty.guides</groupId>
  9  <artifactId>io.openliberty.guides.multimodules.ear</artifactId>
 10  <version>0.0.1-SNAPSHOT</version>
 11  <packaging>ear</packaging>
 12
 13  <parent>
 14    <groupId>io.openliberty.guides</groupId>
 15    <artifactId>io.openliberty.guides.multimodules.modules</artifactId>
 16    <version>0.0.1-SNAPSHOT</version>
 17  </parent>
 18
 19  <dependencies>
 20    <!-- web and jar modules as dependencies -->
 21    <dependency>
 22      <groupId>io.openliberty.guides</groupId>
 23      <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 24      <version>0.0.1-SNAPSHOT</version>
 25      <type>jar</type>
 26    </dependency>
 27    <dependency>
 28      <groupId>io.openliberty.guides</groupId>
 29      <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 30      <version>0.0.1-SNAPSHOT</version>
 31      <type>war</type>
 32    </dependency>
 33    <dependency>
 34      <groupId>junit</groupId>
 35      <artifactId>junit</artifactId>
 36      <version>4.12</version>
 37      <scope>test</scope>
 38    </dependency>
 39  </dependencies>
 40
 41  <build>
 42    <plugins>
 43      <plugin>
 44        <groupId>org.apache.maven.plugins</groupId>
 45        <artifactId>maven-ear-plugin</artifactId>
 46        <version>3.0.1</version>
 47        <configuration>
 48          <modules>
 49            <jarModule>
 50              <groupId>io.openliberty.guides</groupId>
 51              <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 52              <uri>/io.openliberty.guides.multimodules.jar-0.0.1-SNAPSHOT.jar</uri>
 53            </jarModule>
 54            <webModule>
 55              <groupId>io.openliberty.guides</groupId>
 56              <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 57              <uri>/io.openliberty.guides.multimodules.war-0.0.1-SNAPSHOT.war</uri>
 58              <!-- Set custom context root -->
 59              <contextRoot>/converter</contextRoot>
 60            </webModule>
 61          </modules>
 62        </configuration>
 63      </plugin>
 64
 65      <!-- Enable liberty-maven plugin -->
 66      <plugin>
 67        <groupId>net.wasdev.wlp.maven.plugins</groupId>
 68        <artifactId>liberty-maven-plugin</artifactId>
 69        <configuration>
 70          <assemblyArtifact>
 71            <groupId>io.openliberty</groupId>
 72            <artifactId>openliberty-runtime</artifactId>
 73            <version>RELEASE</version>
 74            <type>zip</type>
 75          </assemblyArtifact>
 76          <configFile>src/main/liberty/config/server.xml</configFile>
 77          <packageFile>${package.file}</packageFile>
 78          <include>${packaging.type}</include>
 79          <bootstrapProperties>
 80            <default.http.port>${testServerHttpPort}</default.http.port>
 81            <default.https.port>${testServerHttpsPort}</default.https.port>
 82          </bootstrapProperties>
 83        </configuration>
 84        <executions>
 85          <!-- Copy ear to defaultServer/apps -->
 86          <execution>
 87            <id>install-apps</id>
 88            <configuration>
 89              <looseApplication>true</looseApplication>
 90              <stripVersion>false</stripVersion>
 91              <installAppPackages>project</installAppPackages>
 92            </configuration>
 93          </execution>
 94        </executions>
 95      </plugin>
 96
 97      <!-- Since the package type is ear, need to run testCompile to compile the tests -->
 98      <plugin>
 99        <groupId>org.apache.maven.plugins</groupId>
100        <artifactId>maven-compiler-plugin</artifactId>
101        <version>3.7.0</version>
102        <executions>
103          <execution>
104            <phase>test-compile</phase>
105            <goals>
106              <goal>testCompile</goal>
107            </goals>
108          </execution>
109        </executions>
110      </plugin>
111
112      <!-- Plugin to run integration tests -->
113      <plugin>
114        <groupId>org.apache.maven.plugins</groupId>
115        <artifactId>maven-failsafe-plugin</artifactId>
116        <version>3.0.0-M1</version>
117        <executions>
118          <execution>
119            <phase>integration-test</phase>
120            <id>integration-test</id>
121            <goals>
122              <goal>integration-test</goal>
123            </goals>
124            <configuration>
125              <includes>
126                <include>**/it/**</include>
127              </includes>
128              <systemPropertyVariables>
129                <liberty.test.port>${testServerHttpPort}</liberty.test.port>
130                <running.bluemix>${running.bluemix}</running.bluemix>
131                <cf.context.root>${cf.context.root}</cf.context.root>
132              </systemPropertyVariables>
133            </configuration>
134          </execution>
135          <execution>
136            <id>verify-results</id>
137            <goals>
138              <goal>verify</goal>
139            </goals>
140          </execution>
141        </executions>
142        <configuration>
143          <summaryFile>${project.build.directory}/test-reports/it/failsafe-summary.xml</summaryFile>
144          <reportsDirectory>${project.build.directory}/test-reports/it</reportsDirectory>
145        </configuration>
146      </plugin>
147    </plugins>
148  </build>
149
150</project>

Building the modules

This command creates a JAR file in the jar/target directory, a WAR file in the war/target directory, and an EAR file in the ear/target directory, which contains the JAR and WAR files.

By aggregating the build in the previous section, you can run mvn install once from the start directory and it will automatically build all your modules. Use the following command to build the entire application from the start directory:

mvn install

Since the modules are independent, you can re-build them individually by running mvn install from the corresponding module directory.

Starting the application

To deploy your EAR application on an Open Liberty server, run the Maven liberty:start-server goal from the ear directory:

mvn liberty:start-server

Once the server is running, you can find the application at the following URL: http://localhost:9080/converter/

To stop the server, enter the following command:

mvn liberty:stop-server

Testing the multi-module application

To test the multi-module application, add integration tests to the EAR project.

Create the Test class.
ear/src/test/java/it/io/openliberty/guides/multimodules/Test.java

Test.java

 1package it.io.openliberty.guides.multimodules;
 2
 3import static org.junit.Assert.*;
 4import java.net.HttpURLConnection;
 5import java.net.URL;
 6import javax.net.ssl.HttpsURLConnection;
 7
 8import java.io.BufferedReader;
 9import java.io.InputStreamReader;
10
11public class Test {
12  String port = System.getProperty("liberty.test.port");
13  String war = "converter";
14  String urlBase = "http://localhost:" + port + "/" + war + "/";
15
16  @org.junit.Test
17  public void testIndexPage() throws Exception {
18    String url = this.urlBase;
19    HttpURLConnection con = testRequestHelper(url, "GET");
20    assertEquals("Incorrect response code from " + url, 200, con.getResponseCode());
21    assertTrue("Incorrect response from " + url,
22        testBufferHelper(con).contains("Enter the height in centimeters"));
23  }
24
25  @org.junit.Test
26  public void testHeightsPage() throws Exception {
27    String url = this.urlBase + "heights.jsp?heightCm=10";
28    HttpURLConnection con = testRequestHelper(url, "POST");
29    assertTrue("Incorrect response from " + url,
30        testBufferHelper(con).contains("3    inches"));
31  }
32
33  private HttpURLConnection testRequestHelper(String url, String method) throws Exception {
34    URL obj = new URL(url);
35    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
36    // optional default is GET
37    con.setRequestMethod(method);
38    return con;
39  }
40
41  private String testBufferHelper(HttpURLConnection con) throws Exception {
42    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
43    String inputLine;
44    StringBuffer response = new StringBuffer();
45    while ((inputLine = in.readLine()) != null) {
46      response.append(inputLine);
47    }
48    in.close();
49    return response.toString();
50  }
51
52}

The testIndexPage tests to check that you can access the landing page.

The testHeightsPage tests to check that the application can process the input value and calculate the result correctly.

For a Maven EAR project, the testCompile goal is specified for the maven-compiler-plugin plug-in in your ear/pom.xml file so that the test cases are compiled and picked up for execution.

ear/pom.xml

  1<?xml version='1.0' encoding='utf-8'?>
  2<project xmlns="http://maven.apache.org/POM/4.0.0"
  3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4         xsi:schemaLocation=
  5         "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6
  7  <modelVersion>4.0.0</modelVersion>
  8  <groupId>io.openliberty.guides</groupId>
  9  <artifactId>io.openliberty.guides.multimodules.ear</artifactId>
 10  <version>0.0.1-SNAPSHOT</version>
 11  <packaging>ear</packaging>
 12
 13
 14  <dependencies>
 15    <!-- web and jar modules as dependencies -->
 16    <dependency>
 17      <groupId>io.openliberty.guides</groupId>
 18      <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 19      <version>0.0.1-SNAPSHOT</version>
 20      <type>jar</type>
 21    </dependency>
 22    <dependency>
 23      <groupId>io.openliberty.guides</groupId>
 24      <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 25      <version>0.0.1-SNAPSHOT</version>
 26      <type>war</type>
 27    </dependency>
 28    <dependency>
 29      <groupId>junit</groupId>
 30      <artifactId>junit</artifactId>
 31      <version>4.12</version>
 32      <scope>test</scope>
 33    </dependency>
 34  </dependencies>
 35
 36  <build>
 37    <plugins>
 38      <plugin>
 39        <groupId>org.apache.maven.plugins</groupId>
 40        <artifactId>maven-ear-plugin</artifactId>
 41        <version>3.0.1</version>
 42        <configuration>
 43          <modules>
 44            <jarModule>
 45              <groupId>io.openliberty.guides</groupId>
 46              <artifactId>io.openliberty.guides.multimodules.jar</artifactId>
 47              <uri>/io.openliberty.guides.multimodules.jar-0.0.1-SNAPSHOT.jar</uri>
 48            </jarModule>
 49            <webModule>
 50              <groupId>io.openliberty.guides</groupId>
 51              <artifactId>io.openliberty.guides.multimodules.war</artifactId>
 52              <uri>/io.openliberty.guides.multimodules.war-0.0.1-SNAPSHOT.war</uri>
 53              <!-- Set custom context root -->
 54              <contextRoot>/converter</contextRoot>
 55            </webModule>
 56          </modules>
 57        </configuration>
 58      </plugin>
 59
 60      <!-- Enable liberty-maven plugin -->
 61      <plugin>
 62        <groupId>net.wasdev.wlp.maven.plugins</groupId>
 63        <artifactId>liberty-maven-plugin</artifactId>
 64        <configuration>
 65          <assemblyArtifact>
 66            <groupId>io.openliberty</groupId>
 67            <artifactId>openliberty-runtime</artifactId>
 68            <version>RELEASE</version>
 69            <type>zip</type>
 70          </assemblyArtifact>
 71          <configFile>src/main/liberty/config/server.xml</configFile>
 72          <packageFile>${package.file}</packageFile>
 73          <include>${packaging.type}</include>
 74          <bootstrapProperties>
 75            <default.http.port>${testServerHttpPort}</default.http.port>
 76            <default.https.port>${testServerHttpsPort}</default.https.port>
 77          </bootstrapProperties>
 78        </configuration>
 79        <executions>
 80          <!-- Copy ear to defaultServer/apps -->
 81          <execution>
 82            <id>install-apps</id>
 83            <configuration>
 84              <looseApplication>true</looseApplication>
 85              <stripVersion>false</stripVersion>
 86              <installAppPackages>project</installAppPackages>
 87            </configuration>
 88          </execution>
 89        </executions>
 90      </plugin>
 91
 92      <!-- Since the package type is ear, need to run testCompile to compile the tests -->
 93      <plugin>
 94        <groupId>org.apache.maven.plugins</groupId>
 95        <artifactId>maven-compiler-plugin</artifactId>
 96        <version>3.7.0</version>
 97        <executions>
 98          <execution>
 99            <phase>test-compile</phase>
100            <goals>
101              <goal>testCompile</goal>
102            </goals>
103          </execution>
104        </executions>
105      </plugin>
106
107      <!-- Plugin to run integration tests -->
108      <plugin>
109        <groupId>org.apache.maven.plugins</groupId>
110        <artifactId>maven-failsafe-plugin</artifactId>
111        <version>3.0.0-M1</version>
112        <executions>
113          <execution>
114            <phase>integration-test</phase>
115            <id>integration-test</id>
116            <goals>
117              <goal>integration-test</goal>
118            </goals>
119            <configuration>
120              <includes>
121                <include>**/it/**</include>
122              </includes>
123              <systemPropertyVariables>
124                <liberty.test.port>${testServerHttpPort}</liberty.test.port>
125                <running.bluemix>${running.bluemix}</running.bluemix>
126                <cf.context.root>${cf.context.root}</cf.context.root>
127              </systemPropertyVariables>
128            </configuration>
129          </execution>
130          <execution>
131            <id>verify-results</id>
132            <goals>
133              <goal>verify</goal>
134            </goals>
135          </execution>
136        </executions>
137        <configuration>
138          <summaryFile>${project.build.directory}/test-reports/it/failsafe-summary.xml</summaryFile>
139          <reportsDirectory>${project.build.directory}/test-reports/it</reportsDirectory>
140        </configuration>
141      </plugin>
142    </plugins>
143  </build>
144
145</project>

Enter the following command to run the test from the start/ear directory:

Running the tests

If the server is still running from the previous steps, stop it using the Maven liberty:stop-server goal from command line in the start directory:

mvn liberty:stop-server

Then, verify that the tests pass using the Maven verify goal:

mvn verify

It may take some time before build is complete. If the tests pass, you will see a similar output to the following:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running it.io.openliberty.guides.multimodules.Test
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.712 sec - in it.io.openliberty.guides.multimodules.Test

Results :

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

Great work! You’re done!

You built and tested a multi-module unit converter application on the with Maven in Open Liberty.

Guide Attribution

Creating a multi-module application by Open Liberty is licensed under CC BY-ND 4.0

Copied to clipboard
Copy code block
Copy file contents
Git clone this repo to get going right away:
git clone https://github.com/OpenLiberty/guide-maven-multimodules.git
Copy github clone command
Copied to clipboard

Nice work! Where to next?

What could make this guide better?

Raise an issue to share feedback

Create a pull request to contribute to this guide

Need help?

Ask a question on Stack Overflow

What did you think of this guide?

Extreme Dislike Dislike Like Extreme Like