# Codehaus Cargo : Maven 3 Plugin Tips

Created by Former user, last modified by S. Ali Tokmen on Oct 12, 2023

# Tips

- Starting multiple containers conditionally
- Starting Tomcat in security mode
- How to get Tomcat 5 working with the Java 5 XML Parsers
- How to use the ZIP or TAR.GZ distributions provided by servers on a Maven repository
- How to run Jetty under a Java Security Manager

## Starting multiple containers conditionally

Maven 3 supports the notion of profiles which can be used with Cargo to decide for example when to run tests on a specific container. Here's how you could use the Cargo Maven 3 plugin to that effect:

    <project>
    [...]
      <profiles>
        <profile>
          <id>tomcat5x</id>
          <build>
            <plugins>
              <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven3-plugin</artifactId>
                <configuration>
                  <container>
                    <containerId>tomcat5x</containerId>
                    <zipUrlInstaller>
                      <url>http://www.apache.org/dist/jakarta/tomcat-5/v5.0.30/bin/jakarta-tomcat-5.0.30.zip</url>
                      <downloadDir>${project.build.directory}/downloads</downloadDir>
                      <extractDir>${project.build.directory}/extracts</extractDir>
                    </zipUrlInstaller>
                  </container>
                  <configuration>
                    <home>${project.build.directory}/tomcat5x/container</home>
                  </configuration>
                </configuration>
                <executions>
                  <execution>
                    <id>start-container</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                      <goal>start</goal>
                    </goals>
                  </execution>
                  <execution>
                    <id>stop-container</id>
                    <phase>post-integration-test</phase>
                    <goals>
                      <goal>stop</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
            </plugins>
          </build>
        </profile>
        <profile>
          <id>orion2x</id>
          <build>
            <plugins>
              <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven3-plugin</artifactId>
                <configuration>
                  <container>
                    <containerId>orion2x</containerId>
                    <zipUrlInstaller>
                      <url>http://www.orionserver.com/distributions/orion2.0.5.zip</url>
                      <downloadDir>${project.build.directory}/downloads</downloadDir>
                      <extractDir>${project.build.directory}/extracts</extractDir>
                    </zipUrlInstaller>
                  </container>
                  <configuration>
                    <home>${project.build.directory}/orion2x/container</home>
                  </configuration>
                </configuration>
                <executions>
                  <execution>
                    <id>start-container</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                      <goal>start</goal>
                    </goals>
                  </execution>
                  <execution>
                    <id>stop-container</id>
                    <phase>post-integration-test</phase>
                    <goals>
                      <goal>stop</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
            </plugins>
          </build>
        </profile>
      </profiles>
    </project>

Then to start the tomcat 5.x container you would type `mvn -P tomcat5x install`. if you want to start both containers you would type `mvn -P tomcat5x,orion2x install`.

If you want to define a profile as the default you can use the `<activation>` element with an activation strategy. For example if you want a profile to be always on, use:

    <profiles>
        <profile>
          <id>tomcat5x</id>
          <activation>
            <activeByDefault>true</activeByDefault>
           </activation>
    [...]

## Starting Tomcat in security mode

Warning: the proposed solution only works on Linux, see MNG-6437.

Cargo supports passing system properties. So, to start Tomcat in security mode, you need to specify two system properties:

- `java.security.manager`
- `java.security.policy`

For instance,

    [...]
      <plugins>
        [...]
        <plugin>
          <groupId>org.codehaus.cargo</groupId>
          <artifactId>cargo-maven3-plugin</artifactId>
          <configuration>
            <container>
              <containerId>tomcat5x</containerId>
              <home>${catalina.home}</home>
              [...]
              <systemProperties>
                <java.security.manager>default</java.security.manager>
                <java.security.policy>${catalina.home}\conf\catalina.policy</java.security.policy>
              </systemProperties>
            </container>
          </configuration>
        </plugin>
        [...]
      </plugins>
    [...]

## How to get Tomcat 5 working with the Java 5 XML Parsers

Tip submitted by Ben P.

Imagine that you have some XML jars in the `common/endorsed` folder of Tomcat and you have edited your `catalina.bat` file to specify some extra JVM opts to specify the XML parser. Here's how to achieve the same using Cargo:

    <plugin>
      <groupId>org.codehaus.cargo</groupId>
      <artifactId>cargo-maven3-plugin</artifactId>
      <configuration>
        <container>
          <containerId>tomcat5x</containerId>
          <home>${tomcat.home}</home>
          <dependencies>
            <dependency>
              <location>${tomcat.home}/common/endorsed/xalan.jar</location>
            </dependency>
            <dependency>
              <location>${tomcat.home}/common/endorsed/xercesImpl.jar</location>
            </dependency>
          </dependencies>
          <systemProperties>
            <javax.xml.parsers.DocumentBuilderFactory>
              org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
            </javax.xml.parsers.DocumentBuilderFactory>
            <javax.xml.parsers.SAXParserFactory>
              org.apache.xerces.jaxp.SAXParserFactoryImpl
            </javax.xml.parsers.SAXParserFactory>
          </systemProperties>
        </container>
        <configuration>
          <type>existing</type>
          <home>${tomcat.home}</home>
        </configuration>
      </configuration>
    </plugin>

This shows how to add classpath elements to a Cargo container using the `<dependencies>` element.

## How to run a Jetty webapp under a Java Security Manager

Tip submitted by Claude Brisson

This solution doesn't work on Windows for now: `@cargo.repository@`, `@cargo.container@` and `@cargo.webapp@` should be URIs and not paths.

Jetty 8.x has its own security manager, which can be enabled by enabling the `jetty-policy.xml` module, but it will search for its policies files under a `lib/policy` directory located in the same location as `start.jar`, inaccessible to Cargo's custom configuration folders.

So we'll stick to the Jetty 9.x container. In Jetty 9.x there is no internal security manager, so we'll directly run Jetty 9.x under the standard `java.lang.SecurityManager`.

We'll first need a `mywebapp.policy` policy file. It gives rights to Jetty itself:

src/main/policy/mywebapp.policy Expand source

    ///////////////////////////////////////////////////
    //
    // Give Maven repository libs all permissions
    //
    ///////////////////////////////////////////////////

    grant codeBase "file:@cargo.repository@/-"
    {
        permission java.security.AllPermission "", "";
    };

    ///////////////////////////////////////////////////
    //
    // Give Jetty libs all permissions
    //
    ///////////////////////////////////////////////////

    grant codeBase "file:@cargo.container@/-"
    {
        permission java.security.AllPermission "", "";
    };

    ///////////////////////////////////////////////////
    //
    // Give anyone basic and reflection runtime rights
    //
    ///////////////////////////////////////////////////

    grant
    {
        permission java.lang.RuntimePermission "accessDeclaredMembers";
        permission java.lang.RuntimePermission "getProtectionDomain";
        permission java.lang.RuntimePermission "getClassLoader";
    };

    ///////////////////////////////////////////////////
    //
    // Let webapp resolve classes dependencies
    //
    ///////////////////////////////////////////////////

    grant codeBase "file:@cargo.webapp@/WEB-INF/classes/-"
    {
        permission java.io.FilePermission "@cargo.webapp@/WEB-INF/lib/*", "read";
        permission java.io.FilePermission "@cargo.webapp@/WEB-INF/classes/-", "read";
    };

    grant codeBase "file:@cargo.webapp@/WEB-INF/lib/*"
    {
        permission java.io.FilePermission "@cargo.webapp@/WEB-INF/lib/*", "read";
        permission java.io.FilePermission "@cargo.webapp@/WEB-INF/classes/-", "read";
    };

    ///////////////////////////////////////////////////
    //
    // Let mywebapp be given appropriate rights
    //
    ///////////////////////////////////////////////////

    grant codeBase "file:@cargo.webapp@/WEB-INF/lib/mywebapp.jar"
    {
        // ...
    };

... and then configure appropriately the Cargo Maven 3 plugin:

    <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven3-plugin</artifactId>
        <version>1.6.8</version>
        <configuration>
            <container>
                <containerId>jetty9x</containerId>
            </container>
            <configuration>
                <files>
                    <copy>
                        <file>${project.basedir}/src/main/policy/showcase.policy</file>
                        <todir>/</todir>
                        <configfile>true</configfile>
                    </copy>
                </files>
                <properties>
                    <cargo.container>${project.build.directory}/cargo/installs</cargo.container>
                    <cargo.repository>${settings.localRepository}</cargo.repository>
                    <cargo.webapp>${project.build.directory}/${project.artifactId}</cargo.webapp>
                    <cargo.slf4j.version>${slf4j.version}</cargo.slf4j.version>
                    <cargo.jvmargs>
                        <!-- enable security manager -->
                        -Djava.security.manager
                        -Djava.security.policy=${project.build.directory}/cargo/configurations/jetty9x/my_webapp.policy
                    </cargo.jvmargs>
                </properties>
            </configuration>
        </configuration>
        <executions>
            <execution>
                <configuration>
                    <wait>false</wait>
                </configuration>
                <id>start-server</id>
                <goals>
                    <goal>start</goal>
                </goals>
                <phase>pre-integration-test</phase>
            </execution>
            <execution>
                <id>stop-server</id>
                <goals>
                    <goal>stop</goal>
                </goals>
                <phase>post-integration-test</phase>
            </execution>
        </executions>
    </plugin>