8 Building a Real Application with Maven
This chapter describes how to build such a web application.
- Introducing the Maven Example Application
The example application that you build in this chapter displays a list of people, with their names and age, on a web page. It also allows you to add a new person. The details of the people are stored in a Coherence cache. - About Multi-Module Maven Projects
Maven lets you create projects with multiple modules. Each module is in effect another Maven project. At the highest level, you have a POM file that tells Maven about the modules and lets you build the whole application with one Maven command. - Building a Maven Project
To build the example project, you create the directory, and then create the GAR, WAR, and EAR projects.
Introducing the Maven Example Application
The example application that you build in this chapter displays a list of people, with their names and age, on a web page. It also allows you to add a new person. The details of the people are stored in a Coherence cache.
This application contains the following parts:
-
A Coherence GAR project, which contains a Person POJO (Plain Old Java Object), which you need to build into a Portable Object, a utility class to access the cache, and Coherence cache definitions
-
A Jakarta EE web application, which you need to build into a WAR, which contains a servlet and a deployment descriptor
-
A project to assemble the GAR and WAR into an EAR and deploy that EAR to WebLogic Server
In this example, you can see how to build a multi-module Maven project, with dependencies between modules, and how to assemble the application components into a deployable EAR file that contains the whole application.
The aim of this chapter is to show how to use Maven to build whole applications, not to demonstrate how to write web or Coherence applications, so the content of the example itself, in terms of the servlet and the Coherence code, is quite basic. For specific steps,, refer to Building Jakarta EE Projects for WebLogic Server with Maven and Building Oracle Coherence Projects with Maven.
Parent topic: Building a Real Application with Maven
About Multi-Module Maven Projects
Maven lets you create projects with multiple modules. Each module is in effect another Maven project. At the highest level, you have a POM file that tells Maven about the modules and lets you build the whole application with one Maven command.
Each of the modules are placed in a subdirectory of the root of the top-level
project. In the example, the top-level project is called my-real-app
and the three modules are my-real-app-gar
,
my-real-app-war
, and my-real-app-ear
. The Maven
coordinates of the projects are shown in Table 8-1.
Table 8-1 Maven Coordinates and Packaging Types for Example Application
GroupId | ArtifactId | Version | Packaging |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The following are the files that make up the application:
At the highest level, the top-level POM file points to the three modules:
-
The
my-real-app-gar
directory contains the Coherence GAR project. It contains its own POM, the Coherence configuration files, a POJO/POF class definition (Person.java
) and a utility class that is needed to access the cache (CacheWrapper.java
). -
The
my-real-app-war
directory contains the web application. It contains its own POM, a servlet, and a deployment descriptor. This project depends on themy-real-app-gar
project. -
The
my-real-app-ear
directory contains the deployment descriptor for the EAR file and a POM file to build and deploy the EAR.
Parent topic: Building a Real Application with Maven
Building a Maven Project
To build the example project, you create the directory, and then create the GAR, WAR, and EAR projects.
While it is more natural to start with the top-level POM file, doing this will cause issues if you choose to use the archetypes to create the projects. As such, the top-level POM is created at the end, even though the individual project POM files depend on it.
This section includes the following topics:
- Creating a Directory for the Projects
- Creating the GAR Project
- Creating the WAR Project
- Creating the EAR Project
- Creating the Top-Level POM
- Building the Application Using Maven
Parent topic: Building a Real Application with Maven
Creating a Directory for the Projects
Create a directory to hold the projects, using the following command:
mkdir my-real-app cd my-real-app
Note:
Throughout the rest of this chapter, paths shown are relative to this directory.Parent topic: Building a Maven Project
Creating the GAR Project
This section includes the following topics:
- Creating the Initial GAR Project
- Creating or Modifying the POM File
- Creating or Modifying the Coherence Configuration Files
- Creating the Portable Objects
- Creating a Wrapper Class to Access the Cache
Parent topic: Building a Maven Project
Creating the Initial GAR Project
You can create the GAR project either using an archetype, as described in Creating a Coherence Project from a Maven Archetype, or you can create the directories and files manually:
-
To use the archetype, run the following command:
mvn archetype:generate -DarchetypeGroupId=com.oracle.coherence.archetype -DarchetypeArtifactId=gar-maven-archetype -DarchetypeVersion=14.1.2-0-0 -DgroupId=org.mycompany -DartifactId=my-real-app-gar -Dversion=1.0-SNAPSHOT
-
To create the project manually, use the following commands to create the necessary directories:
mkdir -p my-real-app-gar/src/main/resources/META-INF mkdir -p my-real-app-gar/src/main/java/org/mycompany
Parent topic: Creating the GAR Project
Creating or Modifying the POM File
If you use the archetype, you already have a POM file. Modify that file to match the following example. If you create the project manually, create the POM file (my-real-app-gar/pom.xml
) with the following contents:
<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> <artifactId>my-real-app-gar</artifactId> <packaging>gar</packaging> <parent> <groupId>org.mycompany</groupId> <artifactId>my-real-app</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <dependencies> <dependency> <groupId>com.oracle.coherence</groupId> <artifactId>coherence</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.oracle.coherence</groupId> <artifactId>gar-maven-plugin</artifactId> <extensions>true</extensions> <configuration> <generatePof>true</generatePof> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <forceCreation>true</forceCreation> </configuration> </plugin> </plugins> </build> </project>
Examine the POM file to understand each part of the file:
-
The Maven coordinates
groupId
andversion
are inherited from the top-level POM and the POM only needs to specify theartifactId
and packaging type. Notice that the packaging isgar
because you use the Coherence GAR Maven plug-in to build this project into a Coherence GAR file.<artifactId>my-real-app-gar</artifactId> <packaging>gar</packaging>
-
The coordinates of the parent project are set. These coordinates point back to the top-level POM to allow for inheritance of configuration.
<parent> <groupId>org.mycompany</groupId> <artifactId>my-real-app</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
-
The
dependencies
section identifies any dependencies that this project has. In this case, you depend only on the Coherence library, that is,com.oracle.coherence:coherence:14.1.2-0-0
. Notice that the dependency declaration does not need to include the version because that was inherited from the top-level POM file'sdependencyManagement
section. The scope provided means that this library is just for compilation and does not need to be packaged in the artifact that you build (the GAR file) as it is already provided in the runtime environment.<dependencies> <dependency> <groupId>com.oracle.coherence</groupId> <artifactId>coherence</artifactId> <scope>provided</scope> </dependency> </dependencies>
-
The
plugins
section includes any plug-ins that you want to run during the build that are not automatically included or included plug-ins for which you need to specify additional configuration, like themaven-jar-plugin
. In this case, you must setgeneratePof
totrue
so that the plug-in looks for POJOs with POF annotations and generates the necessary artifacts. You also must tell themaven-jar-plugin
to always regenerate the GAR file. Notice that the versions of the plug-ins are not provided because those are inherited from the top-level POM file'spluginManagement
section.<plugins> <plugin> <groupId>com.oracle.coherence</groupId> <artifactId>gar-maven-plugin</artifactId> <extensions>true</extensions> <configuration> <generatePof>true</generatePof> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <forceCreation>true</forceCreation> </configuration> </plugin> </plugins>
Parent topic: Creating the GAR Project
Creating or Modifying the Coherence Configuration Files
There are three Coherence configuration files that you need in your GAR project. If you use the archetype, the files already exist, but you need to modify them to match the following examples. If you create the project manually, create these files in the following locations:
my-real-app-gar/src/main/resources/META-INF/pof-config.xml my-real-app-gar/src/main/resources/META-INF/coherence-application.xml my-real-app-gar/src/main/resources/META-INF/cache-config.xml
-
The following example shows the contents for the
pof-config.xml
file:<?xml version="1.0"?> <pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config coherence-pof-config.xsd"> <user-type-list> <include>coherence-pof-config.xml</include> <user-type> <type-id>1001</type-id> <class-name>org.mycompany.Person</class-name> </user-type> </user-type-list> </pof-config>
This file requires adding the Person type if you created it with the archetype.
-
The following example shows the contents for the
coherence-application.xml
file:<?xml version="1.0" encoding="ISO-8859-1"?> <coherence-application xmlns="http://xmlns.oracle.com/weblogic/coherence-application"> <cache-configuration-ref>META-INF/cache-config.xml</cache-configuration-ref> <pof-configuration-ref>META-INF/pof-config.xml</pof-configuration-ref> </coherence-application>
This file requires little or no modification if you created it with the archetype.
-
The
cache-config.xml
file must be updated if you have used the archetype.In this file, create a cache named People, with a caching scheme named
real-distributed-gar
and a service name ofRealDistributedCache
, which uses the local backing scheme and is automatically started. If you are not familiar with these terms, see Building Oracle Coherence Projects with Maven. The following shows an example of the file:<?xml version="1.0"?> <cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd"> <caching-scheme-mapping> <cache-mapping> <cache-name>People</cache-name> <scheme-name>real-distributed-gar</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <distributed-scheme> <scheme-name>real-distributed-gar</scheme-name> <service-name>RealDistributedCache</service-name> <backing-map-scheme> <local-scheme/> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> </caching-schemes> </cache-config>
Parent topic: Creating the GAR Project
Creating the Portable Objects
Create the Person object, which will store information in the cache. Create a new Java class in the following location:
my-real-app-gar/src/main/java/org/mycompany/Person.java
package org.mycompany; import com.tangosol.io.pof.annotation.Portable; import com.tangosol.io.pof.annotation.PortableProperty; @Portable public class Person { @PortableProperty(0) public String name; @PortableProperty(1) public int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return this.name; } public int getAge() { return this.age; } }
This POJO tells Coherence what to do with the class. Because the focus of this chapter is on building applications with Maven, it does not go into the details of writing Coherence applications. For more information on Coherence, refer to Building Oracle Coherence Projects with Maven.
Parent topic: Creating the GAR Project
Creating a Wrapper Class to Access the Cache
Create a small wrapper class that you can use to access the cache. Create another Java class in this location:
my-real-app-gar/src/main/java/org/mycompany/CacheWrapper.java
package org.mycompany; import java.util.Map; import java.util.Set; import org.mycompany.Person; import com.tangosol.net.CacheFactory; public class CacheWrapper { private static CacheWrapper INSTANCE = new CacheWrapper(); public static CacheWrapper getInstance() { return INSTANCE; } public Set<Map.Entry<Object, Object>> getPeople() { return CacheFactory.getCache("People").entrySet(); } public void addPerson(int personId, String name, int age) { CacheFactory.getCache("People").put(personId, new Person(name, age)); } }
Later, you can use this class in a servlet to get data from the cache and to add new data to the cache.
Parent topic: Creating the GAR Project
Creating the WAR Project
This section includes the following topics:
- Creating the Initial WAR Project
- Creating or Modifying the POM File
- Creating the Deployment Descriptor
- Creating the Servlet
Parent topic: Building a Maven Project
Creating the Initial WAR Project
You can create the WAR project either using an archetype as described in Building Jakarta EE Projects for WebLogic Server with Maven, or you can create the directories and files manually.
-
To use the archetype, run the following command:
mvn archetype:generate -DarchetypeGroupId=com.oracle.weblogic.archetype -DarchetypeArtifactId=basic-webapp -DarchetypeVersion=14.1.2-0-0 -DgroupId=org.mycompany -DartifactId=my-real-app-war -Dversion=1.0-SNAPSHOT
If you use the archetype, then you must remove any unnecessary files included in the project. For example, the generated
AccountBean.java
file needs to be removed because the updated POM file will not include all of the dependencies needed to compile it. -
To create the project manually, use the following commands to create the necessary directories:
mkdir -p my-real-app-war/src/main/webapp/WEB-INF mkdir -p my-real-app-war/src/main/java/org/mycompany/servlets
Parent topic: Creating the WAR Project
Creating or Modifying the POM File
If you use the archetype, the POM file already exists. Modify that file to match the
following example. If you created the project manually, then create the POM file
(my-real-app-war/pom.xml
) with the following contents:
<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> <artifactId>my-real-app-war</artifactId> <packaging>war</packaging> <parent> <groupId>org.mycompany</groupId> <artifactId>my-real-app</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <dependencies> <dependency> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-gar</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <scope>provided</scope> </dependency> </dependencies> </project>
Examine the POM file to understand each part of the file:
-
As you saw in the GAR project, you only need to set the
artifactId
and packaging type coordinates for this project because thegroupId
andversion
are inherited from the top-level POM file. Notice that the packaging for this project iswar
.<artifactId>my-real-app-war</artifactId> <packaging>war</packaging>
-
Define the parent, as you did in the GAR project:
<parent> <groupId>org.mycompany</groupId> <artifactId>my-real-app</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
-
List the dependencies for this project. In this case, there are two dependencies: the GAR project to access the POJO and utility classes you defined there, and the Servlet API. Because the GAR project is built as part of this example application, you use the
${project.groupId}
and${project.version}
built-in property references to specify thegroupId
andversion
of this dependency.<dependencies> <dependency> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-gar</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <scope>provided</scope> </dependency> </dependencies>
Parent topic: Creating the WAR Project
Creating the Deployment Descriptor
The web application has a simple Jakarta EE deployment descriptor that sets the
display-name
for the web application. It resides at the following
location:
my-real-app-war/src/main/webapp/WEB-INF/web.xml
The following are the contents of this file:
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <display-name>my-real-app-war</display-name> </web-app>
Parent topic: Creating the WAR Project
Creating the Servlet
To create the servlet, locate the MyServlet.java
file:
my-real-app-war/src/main/java/org/mycompany/servlets/MyServlet.java
The servlet displays a list of people that are currently in the cache and allows you to add a new person to the cache. The aim of the section is to learn how to build these types of applications with Maven, not to learn how to write Jakarta EE web applications, hence the use of a simplistic servlet.
package org.mycompany.servlets; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import org.mycompany.Person; import org.mycompany.CacheWrapper; @WebServlet(name = "MyServlet", urlPatterns = "MyServlet") public class MyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); String name = request.getParameter("name"); String age = request.getParameter("age"); if (name == null || name.isEmpty() || age == null || age.isEmpty() || id == null || id.isEmpty()) { // no need to add a new entry } else { // we have a new entry - so add it CacheWrapper.getInstance().addPerson(Integer.parseInt(id), name, Integer.parseInt(age)); } renderPage(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { renderPage(request, response); } private void renderPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // get the data Set<Map.Entry<Object, Object>> people = CacheWrapper.getInstance().getPeople(); PrintWriter out = response.getWriter(); out.write("<html><head><title>MyServlet" + "</title></head><body>"); out.write("<h2>Add a new person</h2>"); out.write("<form name=\"myform\" method=\"POST\">"); out.write("ID:<input type=\"text\" name=\"id\"/><br/>"); out.write("Name:<input type=\"text\" name=\"name\"/><br/>"); out.write("Age:<input type=\"text\" name=\"age\"/><br/>"); out.write("<input type=\"submit\" name=\"submit\" " + "value=\"add\"/>"); out.write("</form>"); out.write("<h2>People in the cache now</h2>"); out.write("<table><tr><th>ID</th><th>Name" + "</th><th>Age</th></tr>"); // for each person in data if (people != null) { for (Map.Entry<Object, Object> entry : people) { out.write("<tr><td>" + entry.getKey() + "</td><td>" + ((Person) entry.getValue()).getName() + "</td><td>" + ((Person) entry.getValue()).getAge() + "</td></tr>"); } } out.write("</table></body></html>"); } }
Check if the user has entered any data in the form. If so, then add a new person to
the cache using that data. Note that this application has fairly minimal error handling. To
add the new person to the cache, use the addPerson()
method in the
CacheWrapper
class that you created in your GAR project.
Print out the contents of the cache in a table. In this example, assume that the
cache has a reasonably small number of entries, and read them all using the
getPeople()
method in the CacheWrapper
class.
Parent topic: Creating the WAR Project
Creating the EAR Project
The EAR project manages assembling the WAR and the GAR into an EAR.
This section includes the following topics:
- Creating the Initial EAR Project
- About the POM File for the Example Application
- About the Deployment Descriptor for the Example Application
Parent topic: Building a Maven Project
Creating the Initial EAR Project
Create the EAR project manually using the following command:
mkdir -p my-real-app-ear/src/main/application/META-INF
There are two files in this project: a POM file and a deployment descriptor:
my-real-app-ear/pom.xml my-real-app-ear/src/main/application/META-INF/weblogic-application.xml
Parent topic: Creating the EAR Project
About the POM File for the Example Application
<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> <artifactId>my-real-app-ear</artifactId> <packaging>ear</packaging> <parent> <groupId>org.mycompany</groupId> <artifactId>my-real-app</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <dependencies> <dependency> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-gar</artifactId> <version>${project.version}</version> <type>gar</type> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-war</artifactId> <version>${project.version}</version> <type>war</type> </dependency> </dependencies> <build> <finalName>my-real-app-ear</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-gar-locally</id> <phase>prepare-package</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-gar</artifactId> <version>${project.version}</version> <type>gar</type> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ear-plugin</artifactId> <configuration> <outputFileNameMapping>@{artifactId}@-@{version}@.@{extension}@</outputFileNameMapping> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> </archive> <artifactTypeMappings> <artifactTypeMapping type="gar" mapping="jar"/> </artifactTypeMappings> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>integration-test</id> <activation> <property> <name>skipITs</name> <value>false</value> </property> </activation> <build> <plugins> <plugin> <groupId>com.oracle.weblogic</groupId> <artifactId>weblogic-maven-plugin</artifactId> <executions> <!--Deploy the application to the server--> <execution> <id>deploy for integration testing</id> <phase>pre-integration-test</phase> <goals> <goal>deploy</goal> </goals> <configuration> <adminurl>${wls.admin.url}</adminurl> <user>${wls.admin.user}</user> <password>${wls.admin.pass}</password> <!--The location of the file or directory to be deployed--> <source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source> <!--The target servers where the application is deployed--> <targets>${wls.ear.targets}</targets> <verbose>true</verbose> <name>${project.build.finalName}</name> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
Examine the POM file to understand each part of the file:
-
As in the previous projects, you only need to specify the
artifactId
, packaging type, and the parent:<artifactId>my-real-app-ear</artifactId> <packaging>ear</packaging> <parent> <groupId>org.mycompany</groupId> <artifactId>my-real-app</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
-
The dependencies on the WAR and GAR projects are listed:
<dependencies> <dependency> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-gar</artifactId> <version>${project.version}</version> <type>gar</type> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-war</artifactId> <version>${project.version}</version> <type>war</type> </dependency> </dependencies>
-
The first plug-in configuration is for the
maven-dependency-plugin
. Configure it to copy the GAR file from themy-real-app-gar
project's output (target) directory into the EAR project:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-gar-locally</id> <phase>prepare-package</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>${project.groupId}</groupId> <artifactId>my-real-app-gar</artifactId> <version>${project.version}</version> <type>gar</type> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>
-
The second plug-in configuration is for the
maven-ear-plugin
. You need to tell it to treat a GAR file like a JAR file by adding anartifactTypeMapping
, as in the following example:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ear-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> </archive> <artifactTypeMappings> <artifactTypeMapping type="gar" mapping="jar"/> </artifactTypeMappings> </configuration> </plugin>
-
The
profile
section adds a third plug-in configuration for theweblogic-maven-plugin
that tells it how to deploy the resulting EAR file. Notice that theadminurl
,user
,password
, andtargets
parameters' values are set to properties that will be defined in the top-level POM file.The profile is activated by adding
-DskipITs=false
to the Maven command line. This makes it easier to build the EAR file without needing to deploy it on every build.<profile> <id>integration-test</id> <activation> <property> <name>skipITs</name> <value>false</value> </property> </activation> <build> <plugins> <plugin> <groupId>com.oracle.weblogic</groupId> <artifactId>weblogic-maven-plugin</artifactId> <executions> <!--Deploy the application to the server--> <execution> <id>deploy for integration testing</id> <phase>pre-integration-test</phase> <goals> <goal>deploy</goal> </goals> <configuration> <adminurl>${wls.admin.url}</adminurl> <user>${wls.admin.user}</user> <password>${wls.admin.pass}</password> <!--The location of the file or directory to be deployed--> <source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source> <!--The target servers where the application is deployed--> <targets>${wls.ear.targets}</targets> <verbose>true</verbose> <name>${project.build.finalName}</name> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile>
After you have completed the POM project, add a deployment descriptor.
Parent topic: Creating the EAR Project
About the Deployment Descriptor for the Example Application
The WebLogic deployment descriptor for the EAR file is located in this file:
my-real-app-ear/src/main/application/META-INF/weblogic-application.xml
The following are the contents:
<weblogic-application> <module> <name>GAR</name> <type>GAR</type> <path>my-real-app-gar-1.0-SNAPSHOT.gar</path> </module> </weblogic-application>
This deployment descriptor provides the details for where in the EAR file, the GAR file should be placed, and what it should be called.
Parent topic: Creating the EAR Project
Creating the Top-Level POM
Create the top-level POM. This is located in the pom.xml
file in
the root directory of your application and contains 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>org.mycompany</groupId>
<artifactId>my-real-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<fmw.version>14.1.2-0-0</fmw.version>
<coherence.version>${fmw.version}</coherence.version>
<weblogic.version>${fmw.version}</weblogic.version>
<wls.admin.url>t3://localhost:7001</wls.admin.url>
<wls.admin.user>weblogic</wls.admin.user>
<wls.admin.pass>password</wls.admin.pass>
<wls.ear.targets>AdminServer</wls.ear.targets>
</properties>
<modules>
<module>my-real-app-gar</module>
<module>my-real-app-war</module>
<module>my-real-app-ear</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.oracle.coherence</groupId>
<artifactId>coherence</artifactId>
<version>${coherence.version}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>4.0.4</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.oracle.coherence</groupId>
<artifactId>gar-maven-plugin</artifactId>
<version>${coherence.version}</version>
</plugin>
<plugin>
<groupId>com.oracle.weblogic</groupId>
<artifactId>weblogic-maven-plugin</artifactId>
<version>${weblogic.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-java-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[17,18),[21,22)</version>
<message>You must use JDK 17 or JDK 21 to build the project</message>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Set the coordinates for the project. These match the parent coordinates that you
specified in each of the three projects. Note that the packaging is
pom
. This tells Maven that this project itself does not create
an artifact. In this example, it simply organizes the build for a set of modules, as
named in the modules
section. There is one module entry for each of
the three subprojects.
-
properties
section: This allows you to define variables that can be used in most locations in the current POM file and any module POM files. The first three variables are ones used to configure themaven-compiler-plugin
. You could have declared themaven-compiler-plugin
as a normal plug-in and added configuration to accomplish the same thing, but using these properties makes for less configuration—a Maven best practice.Next, you have defined the
fmw.version
property to hold the version of Oracle Fusion Middleware that you will use. For convenience, you also define thecoherence.version
andweblogic.version
properties and set their values to the value of thefmw.version
property.Finally, you have defined properties that specify the WebLogic Server URL, credentials, and location to which to target the application for testing.
dependencyManagement
section: This section allows you to centrally manage the versions of dependencies used by the project and all of its modules. In this case, the project only has two external dependencies that are needed for compilation but already provided at runtime: the core Coherence dependency and the Jakarta Servlet API.pluginManagement
section: This section allows you to centrally manage the versions of the plug-ins used by the project and all of its modules. In this example, these include the following plug-ins:gar-maven-plugin
: Assembles the Coherence GAR fileweblogic-maven-plugin
: Deploys the EAR file to WebLogic Server for integration testingmaven-dependency-plugin
: Copies the Coherence GAR file so that it can be included in the EAR filemaven-enforcer-plugin
: Ensures that the build uses a compatible Java versionmaven-ear-plugin
: Assembles the Jakarta EE EAR filemaven-jar-plugin
: Participates in assembling the Coherence GAR filemaven-war-plugin
: Assembles the Jakarta EE WAR file
plugin
section: This section configures the Maven Enforcer Plugin to make sure that the build is run with either JDK 17 or JDK 21.
Parent topic: Building a Maven Project
Building the Application Using Maven
You are now ready to build and deploy the application. Before running Maven to build and deploy the application, there are a few things you may need to know. The following sections will cover these topics:
- What You May Need to Know About Coherence Networking
- What You May Need to Know About Maven Dependency Resolution
- Running Maven to Build and Deploy the Application
- Accessing the Application
Parent topic: Building a Maven Project
What You May Need to Know About Coherence Networking
2024-11-06 18:48:27.677/52.215 Oracle Coherence GE 14.1.2.0.0 <Warning>
(thread=Cluster, member=n/a): Delaying formation of a new cluster; multicast networking
appears to be inoperable on interface 192.168.1.179 as this process isn't receiving even its
own transmissions; consider forcing IPv4 via -Djava.net.preferIPv4Stack=true
coherence.wka
to
127.0.0.1
when starting WebLogic Server. This will
cause Coherence to use unicast instead of multicast and use the network
interface associated with 127.0.0.1. To pass this system property to
WebLogic Server, simply set the JAVA_OPTIONS
environment
variable prior to running the startWebLogic
script. On
macOS or Linux, do the
following:export JAVA_OPTIONS="-Dcoherence.wka=127.0.0.1"
set "JAVA_OPTIONS=-Dcoherence.wka=127.0.0.1"
Parent topic: Building the Application Using Maven
What You May Need to Know About Maven Dependency Resolution
- Fetching dependencies from a Maven repository
- Passing dependencies between modules in a multi-module build
To fetch a dependency from a Maven repository, the dependency must exist in
either a remote repository (for example, Maven Central) or in the local
Maven repository. Any dependency that isn't available in the local Maven
repository is fetched from the remote repository and added to the local
Maven repository. To put build artifacts in the local Maven repository, you
typically run mvn install
. All artifacts in the local
repository can be fetched by Maven builds without any restrictions.
my-real-app-war
module depends on
the my-real-app-gar
module and the
my-real-app-ear
module depends on both the
my-real-app-gar
and
my-real-app-war
. If you try to build the
my-real-app-war
module by itself before building
and installing the my-real-app-gar
module artifacts in the
local Maven repository, you will get an error like
this:[ERROR] Failed to execute goal on project my-real-app-war: Could not resolve
dependencies for project org.mycompany:my-real-app-war:war:1.0-SNAPSHOT: The following
artifacts could not be resolved: org.mycompany:my-real-app-gar:jar:1.0-SNAPSHOT (absent):
Could not find artifact org.mycompany:my-real-app-gar:jar:1.0-SNAPSHOT -> [Help
1]
- Run
mvn install
in themy-real-app-gar
module directory - Run the build with any target, such as
mvn package
, from the top-levelmy-real-app
directory
Maven understands multi-module builds and creates an in-memory structure called
the Maven Reactor that it uses to pass around information about the build to
the various modules. Part of this information is about how to resolve
cross-module dependencies that may not be present in the local Maven
Repository. This allows Maven to build the my-real-app-war
module using the reactor information about the
my-real-app-gar
module that is not in the local
Maven repository.
Parent topic: Building the Application Using Maven
Running Maven to Build and Deploy the Application
my-real-app
):mvn compile mvn package mvn verify mvn install mvn install -DskipITs=false
Maven runs all of the phases up to and including the one named. Table 8-2 shows the effects of each command.
Table 8-2 Effects of Maven Commands
Command | Details |
---|---|
|
Compiles the Java source into target class files. |
|
|
|
|
|
|
Footnote 1 Deployment only happens if the
-DskipITs=false
argument is passed to Maven.
Footnote 2 Deployment only happens if the
-DskipITs=false
argument is passed to Maven.
Remember, the typical Maven build will skip deploying the application unless you
add -DskipITs=false
. This makes it easier to build the
application without having to deploy each time. After the application is
built and successfully deployed, it is time to test the application to
ensure that it is working properly.
Parent topic: Building the Application Using Maven
Accessing the Application
After the application is successfully deployed, simply use the
/my-real-app-war/MyServlet
URL context path to see the application;
for example, http://127.0.0.1:7001/my-real-app-war/MyServlet
.
Parent topic: Building the Application Using Maven