Maven usage tips

comments

Suddenly, I have participated in publishing Diadoc SDK for Java to open source last week. I have no experience in Java development before and my task was to automate building and deploying of existing Java project. In this article I'll share my feeling about Java development and some maven tips I have faced with.

Before getting into my hands, Diadoc SDK for Java was distributed as plain Java source code. Consumers had to compile it on their own. My task was to bring modern tools for building Java source code to redistributable JAR-file.

Fortunately, Java standard tool for building is Maven. IntelliJ IDEA have maven support out of the box, so tooling is in place.

Installing Maven in Windows

Unfortunately, maven does not have an installer for Windows.

To install maven manually:

  • download maven binary zip archive from official download page
  • extract it to some folder (for example, into c:\tools\). If you have downloaded apache-maven-3.3.9.zip, you'll have c:\tools\apache-maven-3.3.9 directory after that.
  • set M2_HOME environment variable to contain this extracted maven directory (for example, set M2_HOME to c:\tools\apache-maven-3.3.9)
  • set PATH environment variable to contain M2_HOME\bin directory (for example, add c:\tools\apache-maven-3.3.9\bin to PATH variable)

Now you'll be able to execute mvn command from Windows shell.

Using Maven

Surprizingly, It was very easy to start using maven:

  • Add pom.xml file to root of repository. It should contains:
    • groupId, artifactId and version of your package
    • dependencies from maven central to it
  • Place source code to src/main/java folder
  • Place tests code to src/test/java folder

Thats all! Now you can use mvn package command to start building jar-file, or mvn test to start all tests supplied.

In result, I wrote following pom.xml.

Tip #1. Fix missing version in jar's manifest.

One point I faced with was to include specified package version number into jar manifest. Unfortunately, maven doesn't set package information by default. To fill SpecificationVersion and ImplementationVersion package properties you should use maven-jar-plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                        <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Tip #2. Consume generated jar file which is not in maven central

There is a few ways to consume this kind of dependency in your pom.xml. One of them is to install jar-file to local maven repository with command:

mvn install:install-file
    -Dfile=path/to/your.jar
    -DgroupId=your.groupId
    -DartifactId=your.artifactId
    -Dversion=your.version
    -Dpackaging=jar
    -DlocalRepositoryPath=path/to/repo
    -DcreateChecksum=true

Imagine you placed this maven repository right in your source control repository, into repo folder. To use this dependency, add following into your pom.xml:

<project>
    ...
    <repositories>
        <repository>
            <id>local-repository</id>
            <url>file://${basedir}/repo</url>
        </repository>
    </repositories>
    ...
    <dependencies>
        <dependency>
            <groupId>your.groupId</groupId>
            <artifactId>your.artifactId</artifactId>
            <version>your.version</version>
        </dependency>
    </dependencies>
    ...
</project>

Tip #3. Consume maven-based project as source code with modules composition

You can include third-party maven-based project to your repository with git-subtree or git-submodule.

Then create top-level pom.xml with pom-packaging and modules definition:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.groupId</groupId>
    <artifactId>your.artifactId-aggregator</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>path/to/subtree/or/submodule/code</module>
        <module>path/to/consuming/code</module>
    </modules>
</project>

In your consuming code's pom.xml add link to parent pom.xml and dependency like:

<project>
    ...
    <parent>
        <groupId>your.groupId</groupId>
        <artifactId>your.artifactId-aggregator</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    ...
    <dependencies>
        <dependency>
            <groupId>your.groupId</groupId>
            <artifactId>your.artifactId</artifactId>
            <version>your.version</version>
        </dependency>
    </dependencies>
    ...
</project>

Conclusion

Thats all for now. Familiarizing with maven was pleasant and easy to use.

Happy coding.

Comments