Fairly Positive

Using Maven Overlays With SiteManager

At work we use Apache Maven to manage the builds and dependencies of our Java-based projects. I’m looking at using Maven Overlays so we can hold some of our SiteManager CMS development (pieces of functionality to extend that CMS, such as custom navigation objects) and have it easily incorporated into the SiteManager WAR file that is deployed to our test and production servers. Basically, a Maven Overlay merges the contents of a project with a WAR file and then create a new WAR file of the merged content. Coupled with a suitable tagging and branching policy in Git and the use of Maven profiles, we should be able to manage development and deployments to different environments. Another benefit of this approach is that I can run an instance of SiteManager on my local development machine from the command line.

We have started using Sonatype Nexus OSS internally to mirror the central maven repositories and provide a place to hold third party JAR files that aren’t available via public servers. The default Nexus installation provides an anonymous user that can access all of the mirrored and local repositories. Our Nexus installation is IP restricted but that is still too public to store commercially licensed artefacts. I created a restricted repository and a new anonymous user that only had access to specified repositories, i.e. not the restricted repository which would need full authentication to access. With the restricted repository in place, I could upload the SiteManager artefacts needed for development.

To obtain the artefacts you need to get a copy of the SiteManager WAR file from the TerminalFour extranet. Make a copy of the WAR file and unpack it to find the SiteManager.jar and Acme.jar files in the WEB-INF/lib directory. You can then upload the WAR file and two jars with appropriate group, artefact and version numbers. If you don’t have a nexus installation you can install the files to the maven repository on your local machine:

1
2
3
4
5
6
7
8
mvn install:install-file -Dfile=SiteManager.war -DgroupId=com.terminalfour \
    -DartifactId=SiteManager -Dversion=7.2.0003 -Dpackaging=war

mvn install:install-file -Dfile=SiteManager.war -DgroupId=com.terminalfour \
  -DartifactId=SiteManager -Dversion=7.2.0003 -Dpackaging=jar

mvn install:install-file -Dfile=SiteManager.war -DgroupId=com.terminalfour \
  -DartifactId=Acme -Dversion=7.2.0003 -Dpackaging=jar

With the artefacts in place you can add the dependencies to your maven project pom.xml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<dependencies>
    <dependency>
        <groupId>com.terminal4</groupId>
        <artifactId>SiteManager</artifactId>
        <version>7.2.0003</version>
        <type>war</type>
        <classifier>SiteManager</classifier>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.terminal4</groupId>
        <artifactId>SiteManager</artifactId>
        <version>7.2.0003</version>
        <type>jar</type>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.terminal4</groupId>
        <artifactId>Acme</artifactId>
        <version>7.2.0003</version>
        <type>jar</type>
        <scope>provided</scope>
    </dependency>
</dependencies>

The scope is naturally set to provided for the JAR files because we only want them available for local development, since they will be provided at runtime in the WAR file. If you are using a Nexus repository to store the SiteManager artefacts you need to tell maven where to find it:

1
2
3
4
5
6
7
<repositories>
    <repository>
        <id>restricted</id>
        <name>Restricted Nexus Repository</name>
        <url>https://example/content/repositories/restricted/</url>
    </repository>
</repositories>

If the repository needs authentication then you will need to configure your ~/.m2/settings-security.xml and ~/.m2/settings.xml files with the encrypted authentication details.

To manage the different deployment environments (local development, test, production etc.) we use profiles to manage resources that are needed for each of these environments. For example, I have a local instance of MySQL for development but we use another vendor on test and production systems.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<profiles>
    <profile>
        <id>local-dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <excludes>
                        <exclude>local-dev/META-INF/*</exclude>
                    </excludes>
                </resource>
            </resources>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>tomcat-maven-plugin</artifactId>
                    <version>1.1</version>
                    <configuration>
                        <contextFile>
                            ${project.basedir}/src/main/resources/local-dev/META-INF/context.xml
                        </contextFile>
                        <path>/terminalfour</path>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.21</version>
            </dependency>
        </dependencies>
    </profile>
</profiles>

The local-dev profile (which is active by default) adds a context.xml that refers to a local MySQL database and makes sure the WAR file has the MySQL JDBC driver. It also sets the deployed context to /terminalfour.

Finally, we need to add the war plugin to the build element of the pom.xml file for the Overlay to work:

1
2
3
4
5
6
7
8
9
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>

So, if we run the following command …

1
mvn tomcat:run-war

… the embedded tomcat server will startup and SiteManager will be available at http://localhost:8080/terminalfour :-D.

Comments