Building BPM and ADF Applications with Maven - Part 2 - Building an ADF WAR

In the first part of this series we looked at how to prepare your Maven repository by importing all of the JDeveloper libraries into it. Now that we have all of the required libraries in our Maven repository, we can work to build our ADF application into a WAR file.

Creating the pom.xml

First, we need to create a pom.xml file within our ADF project. Below is a basic start to the pom.

The important items in this section are:

packaging is set to war

jdev.version is defined and matches the version used when importing the libraries in the previous post

jdev.group.id matches the base group id used when importing the libraries in the previous post

The next piece of the pom we need to set are the dependencies. We have three types of dependencies we will declare in our pom:

Test - These are only used during compilation and execution of our junit tests

Runtime - These are used during compilation and are packaged into our war for use at runtime

Compile - These are only used during compile time and not packaged into the war

In the example below, we have declared two test dependencies, junit and jmock to support our junit test cases. Next are the runtime dependencies. In this sample, we used log4j, so it is included here. We also found that when JDeveloper and ojdeploy build the war file there are some libraries they package into the war. These were the Commons BeanUtils, Commons Collections, Commons Loggging and WSRP Container libraries as well as the bundleresolver jar file. The remaining dependencies were the libraries that were configured for our project within JDeveloper. This list may be different based on the technologies you are using in your ADF project.

<dependencies>

<!-- Test Only Dependencies -->

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>3.8.1</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.jmock</groupId>

<artifactId>jmock</artifactId>

<version>2.5.1</version>

<scope>test</scope>

</dependency>

<!-- Runtime Dependencies, some of these are JDeveloper library files that are being packaged by JDev during a build-->

<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>1.2.17</version>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Commons_Beanutils_1.6</artifactId>

<version>${jdev.version}</version>

<type>pom</type>

</dependency>

<dependency>

<groupId>com.oracle.jdeveloper.jars.jdeveloper.jlib</groupId>

<artifactId>bundleresolver</artifactId>

<version>11.1.1.5.0</version>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Commons_Collections_3.1</artifactId>

<version>${jdev.version}</version>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Commons_Logging_1.0.4</artifactId>

<version>${jdev.version}</version>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>WSRP_Container</artifactId>

<version>${jdev.version}</version>

<type>pom</type>

</dependency>

<!-- Begin JDeveloper Library Dependencies, these are only used at compile time -->

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Model_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Model_Generic_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BPM_Task_Flow</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>JSTL_1.2</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>JSTL_1.2_Tags</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Trinidad_Runtime_11</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>JSF_1.2</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Appserver_Connection</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BPM_Services</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BPM_Worklist_Components</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Resource_Bundle_Variable_Resolver</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_DVT_Faces_Databinding_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Faces_Databinding_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Page_Flow_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Controller_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Controller_Schema</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Faces_Runtime_11</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Common_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Web_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>MDS_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>MDS_Runtime_Dependencies</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>ADF_Common_Web_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>JSP_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Oracle_JEWT</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BC4J_Oracle_Domains</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BC4J_Runtime</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BC4J_Security</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>BC4J_Tester</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Oracle_JDBC</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>${jdev.group.id}</groupId>

<artifactId>Resource_Bundle_Support</artifactId>

<version>${jdev.version}</version>

<scope>provided</scope>

<type>pom</type>

</dependency>

<!-- End JDeveloper Library Dependencies -->

</dependencies>

Configuring the Build

The rest of our pom file, which contains the build configuration, is listed below. We encountered problems with some of the various wizards in JDeveloper if we tried using different source directories so instead we decided to change the Maven configuration to match the standard JDeveloper project structure. You will see that we have configured the source and output directories first. We then had to add adfmsrc as a resource directory as well as some non-source files are contained within the src directory. The next step was to configure the WAR plugin to actually build our artifact. We set the warSourceDirectory to public_html and then the WAR name to include the project name and version. This allows us to have versioned ADF WAR files to match the different versions of our BPM composites that are deployed. Finally, we configured the clean plugin to clean the deploy and classes folders - the default output directories of JDeveloper.

<build>

<sourceDirectory>${basedir}/src</sourceDirectory>

<testSourceDirectory>${basedir}/test</testSourceDirectory>

<outputDirectory>${basedir}/classes</outputDirectory>

<testOutputDirectory>${basedir}/classes</testOutputDirectory>

<resources>

<resource>

<directory>adfmsrc</directory>

</resource>

<resource>

<directory>src</directory>

<includes>

<include>**/*.xml</include>

<include>**/*.xsd</include>

<include>**/*.wsdl</include>

<include>**/*.properties</include>

<include>**/*.jpx</include>

<include>**/*.xml</include>

</includes>

</resource>

</resources>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-war-plugin</artifactId>

<version>2.2</version>

<configuration>

<warSourceDirectory>public_html</warSourceDirectory>

<warName>${project.name}-${project.version}</warName>

</configuration>

</plugin>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-clean-plugin</artifactId>

<version>2.5</version>

<configuration>

<filesets>

<fileset>

<directory>deploy</directory>

<followSymlinks>false</followSymlinks>

</fileset>

<fileset>

<directory>classes</directory>

<followSymlinks>false</followSymlinks>

</fileset>

</filesets>

</configuration>

</plugin>

</build>

</project>

Updating web.xml and weblogic.xml

Now that our WAR builds properly, there is one more step. That is to compare the Maven produced WAR file to the JDeveloper produced WAR file. This will help you confirm that you setup your dependencies and build configuration correctly but also help you find other changes JDeveloper may make at packaging time. I found that both the web.xml and weblogic.xml had additional items added at packaging time. There was no reason these sections should not have been in the web.xml and weblogic.xml at development time, so we took files from the the JDeveloper produced WAR and copied them back into our project to replace the existing ones. These updated files will then be used by the maven build as well. Below are the diff's of our web.xml and weblogic.xml.

web.xml

weblogic.xml

Summary

Putting all four of these sections together you should now have a working pom.xml that will build your ADF project into a WAR file. The main items we had to do in this part were to declare the proper dependencies in the correct scopes, configure the source, output and resource directories to match a standard JDeveloper project structure, and finally configure the WAR plugin to build the project. As you can see here, there are some things that JDeveloper/ojdeploy do that are not well documented. It is important to periodically diff the war that is produced with maven to one produced with JDeveloper to be sure you are not missing any new configurations or libraries.

About the Author

Adam DesJardin is the Chief Technology Officer for AVIO Consulting. Adam focuses on technical strategy, standards and delivery both within AVIO and for our customers. Prior to joining AVIO in 2007, Adam held various consulting and architecture positions at Fuego and BEA Systems where he developed and delivered process and service driven solutions.

AVIO specializes in assisting our clients in achieving their strategic goals as soon as possible. What tomorrow looks like has never been so uncertain and that is why AVIO Consulting has built our firm around quickly understanding and delivering our client's critical projects.