Maven

From Shrubbery

Jump to: navigation, search


Maven tips and notes. See also Migrating to Maven


Personally, there are a lot of things I really don't like about Maven. When it works, it provides a great deal of simplification. When it doesn't work it is almost always a nightmare to figure out what went wrong. In any case, if you do everything the way it wants to do things Maven can make life simpler for building relatively straightforward code bases.

Contents

Generating a stub project

In the parent directory of the project you want to create, use:

$ mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes \
 -DgroupId=com.mycompany.theapp -DartifactId=the-app

This will create a directory called the-app with a pom.xml file, source and test (JUnit) directories.

Getting Maven to compile in Java 5 mode

Add the following in the pom.xml file:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

If there is already a plugins section, simply change the plugin configuration.

See this Java World article

Useful Maven Commands

Compile, run tests

mvn test

Download Dependencies

Project dependencies can be downloaded using the dependency plugin, which can be invoked as a plugin goal from the command line like this:

mvn dependency:copy-dependencies

This will download the dependent libraries from the repositories into the local repository, then copy the files into target/dependency.

The plugin goal can also be bound to a lifecycle phase for convenience. A good place for the dependency plugin is in the generate-sources phase because this happens just before the compile phase.

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>src-dependencies</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <classifier>sources</classifier>
                            <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
                            <outputDirectory>${project.build.directory}/sources</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>dependencies</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

This can be invoked from the command line like this:

mvn generate-sources

Useful Build Plugins

Source JAR Plugin

The following will add a "source:jar" goal that will produce a jar of the source code when added to the project/build/plugins section of pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-source-plugin</artifactId>
  <configuration>
    <finalName>${project.build.finalName}</finalName>
    <attach>false</attach>
  </configuration>
</plugin>

Site Plugin

Generates a project web site using the "site" goal:

<plugin>
  <artifactId>maven-site-plugin</artifactId>
    <configuration>
      <locales>en,fr</locales>
    </configuration>
</plugin>

Basic commands

CommandDescription
mvn compileCompile the main sources.
mvn testCompile the main and test sources, run the tests.
mvn cleanDeletes all the generated files in the target directory.
mvn packageCompile, test, package JAR files.

Just compile and package, don't test

Use -Dmaven.test.skip=true on the command line.

mvn -Dmaven.test.skip=true package

See The Maven FAQ.

Dependencies

Maven dependencies are described by <dependency> elements in the POM file. Maven automatically resolves transitive dependencies for the entire chain of dependents (well, the ones that it has POM files for anyway).

Log4J Dependency

Log4J is in the global Maven repositories, so you can add Log4J to a Maven build using the following in your pom.xml file:

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
</dependency>

However, Log4J now has transitive dependencies on JMX and JMS. If you don't need these you can exclude the transitive dependencies on JMX by adding <exclusions>, for example:

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
  <exclusions>
    <exclusion>
      <groupId>javax.jms</groupId>
      <artifactId>jms</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jdmk</groupId>
      <artifactId>jmxtools</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jmx</groupId>
      <artifactId>jmxri</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Version with square brackets?

Square brackets tell Maven to require the exact version of the dependency, as opposed to the default (no brackets) behavior which is to require the specified version or greater.

For example, this requires Log4J 1.2.15 exactly:

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>[1.2.15]</version>
</dependency>

Whereas, this requires any version >= 1.2.15:

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
</dependency>

See http://maven.apache.org/plugins/maven-enforcer-plugin/rules/versionRanges.html

Troubleshooting

archetype:create doesn't find 1.0-alpha-6 things!

I ran in to this because I was using Java 6. Maven is one of the many tools that don't play nice with Java 6, but unfortunately it doesn't result in an error message that gives the user a hint at what the real problem is. Anyway, if you have this problem make sure you are not using Java 6.

Log4J - Can't resolve JMX and JMS dependencies!

See #Log4J Dependency

Maven Web Site Generation

Using only it's basic features, Maven might seem like overkill when compared to ANT. Web site generation is one of the things that can make Maven much more useful than a straight ANT build, and may even justify the Maven learning curve.

  1. Maven can generate a pretty decent looking project web site for an open source project.
  2. Maven can easily integrate javadoc, unit test reports, cross referenced source code, and other reports into the site. This is usually quite a bit of work with ANT.

See:

Basic Web Site Commands

CommandDescription
mvn siteGenerates the project web site. By default this goes into the target/site directory.

APT (almost plain text) format tips

See also: APT format reference

Links

Links are a little weird in APT. It's not like the common Wiki markups.

External absolute link
{{{http://www.foo.org}the foo website}}
Relative link
{{{./apidocs/index.html}the Javadocs}}
. Note that the address must begin with '.' or '..'.
Section anchor link
{{some section}}
. Note that 'some section' must be the name of a section verbatim.

Advanced Maven

Personal tools