Sunday, June 04, 2017

Apache Maven and SOA 11g. Configure Web Applications


Hello everyone, have a great any time of the day or night. It's time to continue what I've started here. So far, I haven't described anything useful, but extra efforts to maintain all that Maven configuration. Now it's time to get some perks from the situation. I've decided to start from the J2EE for two reasons: highlight the Maven and JDeveloper compatibility issues and how to address them, and create diversified project model (next post will be all about SOA composites).

Project dependencies

Service does a little bit weirdo function - receive Apache FOP XML as the input string and reply with the generated PDF document as a Base64 string. The project itself isn't relevant and you may use any of yours; Although, you may find a real-life scenario: Your SOA composites receive and prepare some data and you want to deliver it as a PDF report, attached to the email (I'm not going to ask you why you don't consider any report management frameworks).  However, I use this example on purpose to stress unlikeness between Maven and JDeveloper in the library management.
Anyone who uses Oracle JDeveloper knows, to compile code project should be aware where to find dependencies. In the Oracle world answer is simple: Libraries. The library allows you to define a group of files and reuse it on your local workstation. If you want to share your project - the library should come along otherwise, your peers wouldn't be able to build your project. To work with our project you will need 2 libraries as on screenshot below: JAX-WS Web Services is the standard one. the second is the custom library and describes Apache FOP framework on my hard drive.


But if we switch to the Maven world, we also should instruct Maven which libraries are required. In the project model terms, we are talking about dependencies. Project file describes what we need to compile and build the project. Normally I think about dependencies as of horizontal links between projects, and of course, links have directions.   The good news, Maven knows where to get your dependencies and dependencies of the dependencies. You don't need to instruct Maven use the JAX-WS libraries, it will find and include appropriate classes automatically. But let's start from the start and create the project POM first.

Maven mode for the project.

You may find more suitable to create application level model first and instruct wizard to create all the project level files as well. But I prefer go in the opposite direction, moving from the project level to the application. I do it as follow:
  1. Open new item wizard by any convenient way (Ctrl+N for example). 
  2. Select General section from the tree on the left 
  3. Start typing maven in the search field.  
  4. There are several options, Select "Maven POM fro Project" one.
  5. Fill the fields with the values as below, or use your own, but write them down for the future reference.
    1. File name:  pom.xml
    2. Directory: your project directory
    3. Group ID: pdf-print-app
    4. Artifact ID: pdf-print-servlet
    5. Version: 0.0.1-SNAPSHOT
    6. Description: Print PDF Web Service
    7. Packaging:  war
  6. Click Ok button and save the new configuration.
  7. Open the pom.xml file for edit. 
Result file should look like the example below.

<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>pdf-print-app</groupId>
  <artifactId>pdf-print-servlet</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src/</sourceDirectory>
    <outputDirectory>classes/</outputDirectory>
    <resources/>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
          <source>
            1.6
          </source>
          <target>
            1.6
          </target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Configure Web application 

You may or may not noticed, but there are not enough information to properly build our project. For the first of all, there are no dependencies, the wizard has forgotten to add packaging information to the project. Also, it would be nice to keep our WEB-INF/** files, it's the place where JDeveloper keeps  web.xml and weblogic.xml. Let's take a look at the final pom.xml file and I'll explain all the changes.

<?xml version="1.0" encoding="windows-1252" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>pdf-print-app</groupId>
  <artifactId>pdf-print-servlet</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop -->
  <dependencies>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>fop</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <resources>
      <resource>
        <directory>${basedir}/public_html/</directory>
        <excludes>
            <exclude>WEB-INF/**</exclude>
        </excludes>
      </resource>
    </resources>
    <sourceDirectory>${basedir}/src/</sourceDirectory>
    <outputDirectory>classes/</outputDirectory>
    <testSourceDirectory>${basedir}/test</testSourceDirectory>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
          <source>
            1.6
          </source>
          <target>
            1.6
          </target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
        <configuration>
          <warSourceDirectory>${basedir}/public_html</warSourceDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

The first change is <dependencies/> section. I don't use any non-J2EE classes but Apache FOP libraries, so I instruct Maven what should be available to successfully compile classes. The new element here is <scope>. With the scope "provided" I tell "don't bother to include dependencies to the package, it will be provided by the environment".
In the build section, I have specified where to find resources. All the static Web content JDeveloper keeps under public_html folder. But I don't want to include anything under WEB-INF folder, it's a place to keep web application metadata.
The next group of the parameters is:

  • sourceDirectory - Place where to find a source code. If you have more than one source location, you may add them under resources section.
  • outputDirectory - Directory to store your compiled Java code. 
  • testDirectory  -  By default, Maven looking for JUnit test source under src/test/** folder. I prefer to keep it next to the src/ folder and maintain the same package structure. 
The source and output folders are quite similar to the default values, and points to the same location, but the ${basedir}/ suffix changes default behavior. if we keep default value src/  Maven looks for the source code in src/java/**  folders, with the base dir we point to the exact location, so it will find our src/** classes.
And the last but not least,  Maven war plugin configuration. Option warSourceDirectory points to the place where plugin should find and reuse WEB-INF folder (yep, web.xml and weblogic.xml).

Build a Package 

Well, it's time to check if we have configured web application properly. Let's build our web application archive. We are not ready to run our fancy external tools, so we just run it from the context menu:
  1. Select project pom.xml in the Application Navigator.
  2. Right click on the pom.xml and select Run Goal(s)->package


After a while, you should see build result in the Apache Maven log window.














Lucky me, there are no errors.  Time to check if the result meets our expectations.  By default, Maven uses target/ folder to package artifacts. The result on the screenshot looks fine for me. 

It has:
  • Proper directory structure 
  • It doesn't contain any libraries. 
  • Web application descriptors are included. 
You can't deploy this application to the WebLogic, unless you deploy Apache FOP libraries first. Other optios:
  1. Comment Apache FOP dependency scope and rebuild package. All the dependencies will be added.
  2. Follow me and build EAR application with the all libraries placed there.
Enjoy, and have a great weekend. 


Post a Comment