Using Maven 2 to Build WebLogic Portal Applications

The purpose of this tutorial is to show how to create a build system for BEA WebLogic Portal using the Apache Maven 2 project. Maven is an open-source build system that is used on many Apache projects. It provides a number of interesting features that go beyond Ant, the most compelling being the dependency management features. The debate about Maven versus Ant is often a heated one, and this tutorial will not be addressing this issue; instead, it will focus solely on the use of Maven 2 with WebLogic Portal.

This tutorial assumes that you are familiar with Maven 2 and the basic functionality it provides. If you are new to Maven, a recommended resource is the free e-book Better Builds with Maven 2.

Setting Up Maven

The first step to take is to install a copy of Maven 2, which can be done by downloading it from the Maven Web site at http://maven.apache.org. Maven can be installed in any location on the file system, however you should not install it in a project-specific directory since you may want to utilize it across different projects.

Once Maven is installed, the next step is to create a small command file to initialize the Maven environment. An example file is shown below; this file is for Windows although it would be simple to create an equivalent for Linux or Solaris.

set BEA_HOME=C:\bea92
set M2_HOME=C:\java\maven-2.0.4

set JAVA_HOME=%BEA_HOME%\jdk150_04
set path=%JAVA_HOME%\bin;%path%;%M2_HOME%\bin
mvn --version

This script simply sets certain environment variables that will be used by the build environment. Obviously, you should change the BEA_HOME, JAVA_HOME, and M2_HOME variables to reflect your specific environment. The end of the script runs the Maven version command to ensure the script is correct. This command simply displays the version of Maven that is being used.

Creating the Maven Repository

A key feature of Maven is the management of dependencies. A build that depends on a resource declares a dependency in the Maven build file, specifying the dependency's group, name, and version. When the build is invoked, Maven resolves these resource dependencies by fetching the necessary resources from a repository. To facilitate this, Maven maintains a large repository at http://repo1.maven.org/maven2 that includes most of the popular open-source frameworks like Spring.

Unfortunately, this repository cannot host commercial resources such as WebLogic libraries because this would violate various copyrights and licensing agreements. As a result, the next step is to install the WebLogic libraries into a local repository. As a first thought, developers may be tempted to simply refer to the resources on the file system using the system scope, however as we will see later this will not work in the case of shared libraries. Additionally, it goes against the philosophy of Maven and therefore should be avoided.

Installing Stand-alone JARs

Installing the stand-alone JARs from your BEA home directory is quite simple. Below is a sample line from a script that shows how to do this using the Maven install plug-in and the install-file goal. For the sake of conciseness, only a single line is shown; the full script is included in the sample code. This script assumes that you are using WebLogic Portal 9.2. If you have installed MP1 or a later version, it is recommended you update the version numbers in the script accordingly.

mvn install:install-file
    -Dfile=%BEA_HOME%\weblogic92\server\lib\weblogic.jar
    -DgroupId=weblogic-server
    -DartifactId=weblogic
    -Dversion=9.2.0
    -Dpackaging=jar
    -DgeneratePom=true

Maven resources are stored in a repository with a group identifier, an artifact identifier, and a version number. The group identifier is used to group similar artifacts together. In the case above, we use weblogic-server to group WebLogic Server-specific artifacts. Later on in the tutorial we will also introduce the weblogic-portal and weblogic-common groups as well. The artifact identifier uniquely identifies the specific artifact. For the sake of clarity, we recommend that the name of the JAR be used as the artifact identifier.

Note that the group and artifact identifiers are exactly what we used to develop this tutorial. Developers are free to use whatever hierarchy and naming convention they prefer, but any changes need to be reflected in all of the build artifacts that accompany this tutorial.

Once the WebLogic resources are in the library, referencing the resource in Maven's project object model (POM) is straightforward. With respect to the previous example of installing the weblogic.jar in the repository, we would create a dependency on this in pom.xml, as shown below.

<dependency>
    <groupId>weblogic-server</groupId>

    <artifactId>weblogic</artifactId>
    <version>9.2.0</version>
    <scope>provided</scope>
</dependency>

Note that the group and artifact identifier along with the version are identical to what we used to install weblogic.jar in the Maven repository. The provided scope simply indicates that the resource is provided at runtime and should be used only for compilation purposes.

Working with Shared Libraries

Unfortunately, we now face a more difficult challenge, namely installing WebLogic's shared libraries into the repository. A shared library is a Web or enterprise archive that is merged at runtime with an application. Applications declare dependencies on shared libraries in either the weblogic-application.xml in an EAR or weblogic.xml in a WAR. These shared libraries can include a variety of resources such as JAR files.

The problem with a shared library is that the Java compiler, javac, is not able to extract the JAR files from the shared library to perform a compilation. In WebLogic Workshop there is a plug-in that expands all the shared libraries into one of the workspace's plug-in directories so that the individual JAR files will be available to the compiler.

With respect to Maven, to access shared libraries we need to install each artifact in each shared library into the Maven repository. To accomplish this goal, a small maven plug-in called maven-weblogic-library-plugin was written to accompany this tutorial. This plug-in works similarly to the Maven install plug-in except it installs one or more shared libraries into the repository. Here is an example of how to execute it:

mvn weblogic-maven:maven-shared-library-plugin:install-library
    -DgroupId=weblogic-portal
    -Ddirectory=%BEA_HOME%/weblogic92/portal/lib/modules
    -DdefaultVersion=9.2.0

This plug-in can install either a single share library using the -Dlibrary switch or all libraries in a specified directory, as shown above. The groupId that is specified above is the root group into which to install the shared library. The plug-in will automatically create a secondary group for the library artifacts whose name is the same as the library. Under this secondary group, each artifact from the shared library will be installed along with a copy of the library itself. Finally, a parent Project Object Model (POM) artifact will be created that can be used to create dependencies on all of the artifacts in the library. This saves on the effort of creating a dependency on each individual artifact when setting up the build.

Versioning

The maven-weblogic-library-plugin plug-in allows the developer to specify the default version of the shared library. This is used when the shared library does not include a version number in its name. If a shared library such as beehive-controls-1.0.ear is installed, the version number will be taken from the name, in this case 1.0, instead of coming from the default version number.

Building the maven-weblogic-library-plugin Plug-in

To build the plug-in, go to the /maven/maven-weblogic-library-plugin folder in the sample code and execute mvn:package followed by mvn:install. Remember to first initialize the Maven environment using the included maven.bat file discussed earlier.

Installing the Shared Libraries

Now that we have the plug-in, the next step is to install all of the shared libraries into the repository. Included in the sample code is a script, install-weblogic-libraries.bat, that shows how to do this.

Once the shared libraries are installed we can include dependencies on them by using the parent POM that our plug-in created, as discussed earlier. For example, to declare a dependency on the p13n-app-lib.ear shared library, we would use the following dependency declaration in our pom.xml:

<dependency>

    <groupId>weblogic-common.p13n-app-lib</groupId>
    <artifactId>p13n-app-lib-parent</artifactId>
    <version>9.2.0</version>
    <type>pom</type>

    <scope>provided</scope>
</dependency>

Creating the Project Object Models

After all that work we are now ready to create our POM files to enable Maven to build our portal application. First, though, a quick word is needed about the portal project structure in WebLogic Workshop. Maven is a tool that is based on the concept of convention over configuration; this means that it expects things to be laid out in a certain way. With respect to portal project structure, Maven has a structure that it prefers for Java and Web projects, and it is recommended that this structure be used when possible.

Using the Maven preferred structure is straightforward; when creating your WebLogic Portal WAR, simply specify the paths to the source and the Web content directories, as shown below. Note that while this is the recommended structure, if you have an existing project that uses the default paths, you can still configure Maven to build the project, but you will need additional configuration settings in the POM to inform Maven of the changed paths.

New Portal Web Project
Figure 1. Eclipse new portal Web project dialog

With respect to the WebLogic Portal EAR, the default structure works just fine with Maven, and no changes are needed.

As a final note on project structure, it is highly recommended that when creating a new project that the source code for the project be placed outside the workspace into a separate directory. This makes the project much easier to manage under source control since there is no temptation to check in unneeded workspace artifacts. The diagram below is an example structure used for this tutorial that illustrates this.

Structure
Figure 2. Example project structure

Now we can finally create our various POM files for each part of the application. In total, we will have three POM files, as discussed in subsequent sections. Note that full versions of each POM are included in the sample code and thus we will only be highlighting the prominent aspects of each POM in the sections below, in particular those areas that relate to building a WebLogic Portal application. Creating and using POMs is well documented on the Maven site and this information will not be duplicated here.

Parent POM

The first POM we will create is the parent POM. This file enables us to build both the EAR and WAR as one unit and allows the centralization of certain settings. While in Maven each artifact, such as the EAR and WAR, is a separate entity, given their intimate nature you will most likely be building and deploying them as a unit.

Within this parent POM we declare modules for the portalEAR and portalWAR projects as follows:

<modules>
    <module>portalEAR</module>

    <module>portalWAR</module>
</modules>

This declaration is what enables us to build both projects at the same time. Note that this is not strictly necessary and is provided as a convenience, since the portalEAR also declares a dependency on portalWAR in its POM, and so the war file will automatically be built by Maven if it has not been built previously.

Next, we configure the maven-compiler-plug-in to target JDK 5 for compile purposes, as shown here:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.5</source>

        <target>1.5</target>
    </configuration>
</plugin>

Web Application POM

The Web application POM is used to build the WAR represented by the portalWAR project. In general, building a WebLogic Portal WAR is no different than building a standard Java EE WAR as supported by Maven. However, we do need to support annotations given that WebLogic Portal applications typically make use of page flows and Beehive annotations.

The JDK includes an annotation processing tool (APT), and Maven 2 does have a plug-in that wraps this tool, maven-apt-plugin, which can be found here. At the time this tutorial was written, the maven-apt-plugin had a few rough edges that prevented it from working correctly with a WebLogic Portal application. A patched version that corrects these deficiencies is included in the sample code and will need to be built first. This patched version can be built and installed running the mvn:package and mvn:install command in the maven-apt-plugin directory. To avoid version conflict, this version is labeled with a -BEA label.

Note that since the time this article was written, the maven-apt-plugin has been corrected to fix the deficiencies noted here. Thus you have the choice of using the plugin included with this article or using the snapshot version of the maven-apt-plugin. If you use the snapshot version of the maven-apt-plugin, the sourcePath configuration option is no longer required and can be removed from the pom.xml for the portalWAR project.

Having Maven process the annotations is straightforward, and the section of the POM that does so is shown below:

<plugin>
    <groupId>org.apache.myfaces.tobago</groupId>
    <artifactId>maven-apt-plugin</artifactId>

    <version>1.0.10-BEA</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>

                <goal>execute</goal>
            </goals>
            <configuration>
                <generated>.apt_generated</generated>
                <aptOptions>

                    x=3,
                    web.content.root=${basedir}/src/main/webapp
                </aptOptions>
                <target>1.5</target>
                <nocompile>true</nocompile>
                <showWarnings>true</showWarnings>

                <verbose>false</verbose>
                <fork>false</fork>
                <sourcePath>${basedir}/src/main/java</sourcePath>
            </configuration>

        </execution>
    </executions>
</plugin>

The key item here is that we set the web.content.root property to point to the Web content source directory as this parameter is required by the Beehive annotation processor. The other parameter of interest is the sourcePath. This was added to the patched version of maven-apt-plugin as it is required by the APT tool.

The last item of interest is the dependencies on the various WebLogic Server and WebLogic Portal libraries and shared libraries. These are included at the bottom of the POM and can be viewed by downloading the sample code.

Enterprise Application POM

The POM for the portalEAR project is, for the most part, a standard POM that could be used with any Java EE application. The configuration of the maven-ear-plugin appears as follows:


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <configuration>
        <displayName>

            Portal Maven2 Sample Application
        </displayName>
        <description>
            Portal Maven2 Sample Application
        </description>
        <version>1.4</version>
        <earSourceDirectory>EarContent</earSourceDirectory>

        <earSourceExcludes>**/application.xml</earSourceExcludes>
        <modules>
            <webModule>
                <groupId>portal-maven2-sample</groupId>
                <artifactId>portalWAR</artifactId>

                <contextRoot>/portalWAR</contextRoot>
            </webModule>
        </modules>
    </configuration>
</plugin>

The only item of interest here is that we exclude the application.xml file and allow Maven to generate this file for us. This is required since the portalWAR will be generated with a version number appended to it as per Maven conventions, and allowing Maven to generate the application.xml ensures the correct module name is used.

Building the Application

Now that we have all the pieces, building the portal application is as easy as running mvn:package from the /applications directory. If you check the target directory under the portalWAR and portalEAR folders you should see copies of the WAR and EAR respectively.

Sample Code

This tutorial includes an archive that contains a sample WebLogic Portal application with all the resources needed to build the application using Maven 2. To use this sample, simply unpack the archive, ensuring that paths are preserved, and then modify maven/scripts/maven.bat to point to the location of your BEA and Maven home directories.

Summary

Building WebLogic Portal applications in Maven 2 can be accomplished with a little bit of effort. The various features included with Maven 2 make it an attractive option to many organizations, and this tutorial should assist you in integrating Maven 2 with WebLogic Portal.

References

Posted by Gerald Nunn | |