Red Hat Training

A Red Hat training course is available for Red Hat Fuse

5.3. Modifying an Existing Maven Project

Overview

If you already have a Maven project and you want to customize it to generate a FAB, perform the following steps:

Ensure that the package type is JAR

A FAB is packaged as a regular JAR file, which is the default package type in Maven. Ensure that the packaging element in your project's pom.xml file contains the value, jar, as shown in the following example:
<project ... >
  ...
  <packaging>jar</packaging>
  ...
</project>

Customize the JDK compiler version

It is almost always necessary to specify the JDK version in your POM file. If your code uses any modern features of the Java language—such as generics, static imports, and so on—and you have not customized the JDK version in the POM, Maven will fail to compile your source code. It is not sufficient to set the JAVA_HOME and the PATH environment variables to the correct values for your JDK, you must also modify the POM file.
To configure your POM file, so that it accepts the Java language features introduced in JDK 1.6, add the following maven-compiler-plugin plug-in settings to your POM (if they are not already present):
<project ... >
  ...
  <build>
    <defaultGoal>install</defaultGoal>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Configure class sharing

Any dependencies on standard artifacts already provided by the container should be declared as provided, to prevent the FAB runtime from unnecessarily installing those dependencies again. This typically includes artifacts whose names match the patterns, camel-*, cxf-*, activemq-*, and fabric-*.
For example, if you have an existing dependency on the camel-http artifact, you should modify the dependency by adding the scope element as follows:
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-http</artifactId>
    <version>2.10.0.redhat-60024</version>
 <scope>provided</scope>
</dependency>
Note
All dependencies with Maven group ID org.apache.camel, org.apache.cxf, or org.apache.activemq are shared by default (equivalent to provided scope), so that the value of the scope element is ignored by default. This behavior changes, however, if the FAB-Provided-Dependency manifest header is specified explicitly—see the section called “Sharing dependencies” for details.
If you have a large number of dependencies to manage, it might be easier to share the standard container artifacts by adding a FAB manifest header. For details, see Example 5.1, “Configuring FAB Manifest Headers in the POM”.

Mark test artifacts with the test scope

Any artifacts needed only for testing must be marked with the test scope, as in the following example:
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>${log4j-version}</version>
 <scope>test</scope>
</dependency>
Of course, this is the standard convention in POM files. But it is particularly important to observe this convention with FAB projects. For any test artifacts that are not marked as such, the FAB runtime will attempt to download and install the test artifact into the container at run time.
Important
Because the test-only artifacts are not intended to be installed in the container, it is quite likely that a FAB will fail to deploy properly if test artifacts are not marked with the test scope.

Specify the requisite dependencies for WS applications

Make sure that you declare all of the requisite dependencies for an Apache CXF application and declare these dependencies with provided scope. For example, a basic Apache CXF application that uses the JAX-WS frontend needs the following Maven dependencies:
<project>
    ...
    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>2.6.0.redhat-60024</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>2.6.0.redhat-60024</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>2.6.0.redhat-60024</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.0.6.RELEASE</version>
            <scope>provided</scope>
        </dependency> 
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Prefer Blueprint over Spring

If your project uses dependency injection or XML configuration, you should prefer the Blueprint framework over the Spring framework.
Because Blueprint is more tightly integrated with OSGi, it is usually able to find whatever dependencies it needs dynamically at deploy time. By contrast, dependencies introduced by a Spring XML file are more likely to lead to ClassNotFound exceptions at deploy time (FAB is not capable of parsing a Spring XML file to discover the dependencies it introduces).

Optionally configure JAR manifest headers

Although the FAB runtime obtains most of its deployment metadata by scanning the pom.xml file embedded in the JAR, you can also specify FAB-specific configuration settings by adding headers to the JAR's manifest. For example:
FAB-Version-Range-Digits: 2
FAB-Provided-Dependency: org.acme.foo:* org.apache.camel:* org.apache.cxf:* org.apache.activemq:*
For detailed explanations of all the FAB manifest headers, see Section 5.4, “Configuring a FAB”.