Homepage/ blog/ 2015/ 07/ Maven example project for Java

Maven is a software project management and comprehension tool, so in other words it can be used to manage all software cycle. This software it helps me a lot in my works and personal projects and in this post I try to share some knownledge and information that I learned.

I create a simple project available on github, click here to get the example. I hope it will help you on your job or personal project(s).

In this post I will try cover all maven lifecycle using my sample project:

  1. Clean: remove all files generated by the previous build. This phase is outside the default lifecycle and it is possible to execute using "Goals" (see "How To build")
  2. Validate: validate the project is correct, for example by analying source code, and all necessary information is available
  3. Compile: compile the source code of the project
  4. Test: test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  5. Package: take the compiled code and package it in its distributable format, such as a JAR.
  6. Integration-test: process and deploy the package if necessary into an environment where integration tests can be run (missing in my example )
  7. Verify: run any checks to verify the package is valid and meets quality criteria (missing in my example )
  8. Install: install the package into the local repository, for use as a dependency in other projects locally
  9. Deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

You found after explanation about pom.xml a little "How To build" and "How To execute".


Explanation about pom.xml

Validate

It is possible to check and Validate source code with different tools:

  • checkstyle: a development tool to help programmers write Java code that adheres to a coding standard, example: check formatting code, check naming conventions, ... . Add the following lines in pom.xml:

     

    <project ...> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>2.15</version> <executions> <execution> <id>verify-java-code</id> <phase>verify</phase> <configuration> <encoding>UTF-8</encoding> <!-- Output errors to console. --> <consoleOutput>true</consoleOutput> <!-- Build should fail upon a violation. --> <failsOnError>true</failsOnError> <!-- If you have some class to exclude use "exclude" node --> <!--<excludes>org/pirola/maven_example/MavenExample.java</excludes>--> </configuration> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> ... <plugins> ... </build> ... </project>


  • findbugs: a program which uses static analysis to look for bugs in Java code by applyng some patterns. Add the following lines in pom.xml:

     

    <project ...> ... <build> ... <plugins> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> <version>3.0.1</version> <configuration> <!-- Max level of analisys and error reporting. --> <effort>Max</effort> </configuration> <goals> <goal>check</goal> </goals> </plugin> ... <plugins> ... </build> ... </project>


  • Sonar: Sonar is a great tools that can analyse your code and get you a Web Interface to view the results. The Web Application is simple and intuitive, I found it very usefull and well done but analysis the code it takes some times. Because it takes some times to have the result I prefer to create a profile and execute it when I have a relatively stable version. Add the following lines in pom.xml:

     

    <project ...> ... <!-- Begin profile. --> <profiles> <profile> <!-- Sonar profile, useful for analyze/validate Java code. --> <id>sonar</id> <activation> <activeByDefault>false</activeByDefault> </activation> <properties> <!-- Example for H2 --> <sonar.jdbc.url> jdbc:h2:tcp://localhost:9092/sonar </sonar.jdbc.url> <sonar.jdbc.username>sonar</sonar.jdbc.username> <sonar.jdbc.password>sonar</sonar.jdbc.password>
    <!-- Optional URL to server. Default value is http://localhost:9000 --> <sonar.host.url> http://localhost:9000 </sonar.host.url> </properties> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>sonar</id> <phase>install</phase> <goals> <goal>sonar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> <!-- End profile. --> ... </project>


Declare Java version you are using either for source code and for the compiler

 

<project ...> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <!-- The -source argument for the Java compiler. 1.7 stand for Java 7. --> <source>1.7</source> <!-- The -target argument for the Java compiler. 1.7 stand for Java 7. --> <target>1.7</target> <!-- Show source locations where deprecated APIs are used. --> <showDeprecation>true</showDeprecation> <!-- Show compilation warnings. --> <showWarnings>true</showWarnings> </configuration> </plugin> ... <plugins> ... </build> ... </project>


Generate and save a version/build number for the code compiled and other informations in a special file called Manifest, see Oracle documentation for more information.

In order to have a reproducible build the version number is only store last git sha version on scm-version.

 

<project ...> ... <!-- Fake URLs. This fake URL is used to fail search remote repository and it use instead the local repository (see buildnumber-maven-plugin). --> <scm> <connection>scm:git:http://none</connection> <url>scm:git:https://none</url> </scm> ... <build> ... <plugins> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> <version>1.3</version> <executions> <execution> <id>set-build-properties</id> <phase>validate</phase> <goals> <goal>create</goal> </goals> </execution> </executions> <configuration> <!-- It will first check to see if you have locally modified files, and will fail if there are any. --> <doCheck>true</doCheck> <!-- If this is made true, then the revision will be updated to the latest in the repo, otherwise it will remain what it is locally --> <doUpdate>true</doUpdate> <!-- This ensures that even if we are not connected to scm than also take the version from local .svn file --> <format>{0}</format> <items> <item>scmVersion</item> </items> <!-- If the plugin fails to get the scm revision, set it to "unavailable" --> <revisionOnScmFailure>unavailable</revisionOnScmFailure> </configuration> </plugin> ... </build> </project>


Test

In this phase it is possible to test your software via automatic test. In my example I use JUnit to test the return of the function "getGreeting", please see src/test/java/org/pirola/maven_example/test/TestGreeting class. In order to use Junit you need to add the following lines:

 

<project ...> ... <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> ... </project>


Package

It is possible to choose different packaging such as: JAR, WAR, EAR, ...

project.mainClass and project.vendor are defined as project properties (see pom.xml: project → properties).

In my example I choose to create an executable JAR by adding the following lines:

 

<project ...> ... <packaging>jar</packaging> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- Update Manifest file (META-INF/MANIFEST.MF) with the new informations. So this "transformation" will add the following lines: - Main-Class: THE program entry point; - Implementation-Title: the title of the implementation; - Implementation-Version: information retrieved from pom.xml (this file). See project -> version node; - Implementation-Vendor: the vendor of the implementation; - Scm-Revision: with git sha, "unavailable if it is impossible to retrieve. --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>${project.mainClass}</Main-Class> <Implementation-Title>${project.name}</Implementation-Title> <Implementation-Version>${project.version}</Implementation-Version> <Implementation-Vendor>${project.vendor}</Implementation-Vendor> <Scm-Revision>${buildNumber}</Scm-Revision> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> </project>


In this phase it is possible to generate javadoc files (html pages) by adding the following lines:

 

<project ...> ... <packaging>jar</packaging> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.10.3</version> <executions> <execution> <id>attach-javadocs</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> ... </plugins> ... </build> </project>


Deploy

In this phase is possible deploy your final JAR to remote server.

For security reason is better save username and password in a different file than pom.xml.

In order to do this you need with the following steps:

  1. Create file settings.xml in your .m2 directory (/home/[user]/.m2 or C:\Users\[user]\.m2)

     

    <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
    <servers> <server> <id>develop-server</id> <username>example</username> <password>password1234</password> </server> </servers>

    </settings>


  2. Add the following lines to pom.xml:

     

    <project ...> ... <packaging>jar</packaging> ... <build> ... <plugins> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <version>1.0</version> <dependencies> <dependency> <!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.9</version> </dependency>
    </dependencies>
    <executions>
    <execution> <id>execute-test-commands</id> <phase>deploy</phase> <goals> <goal>upload</goal> </goals> <configuration> <serverId>develop-server</serverId> <!-- URL to upload final jar --> <url>scp://example.com</url> <!-- Input directory (local) --> <fromDir>${project.build.outputDirectory}/../</fromDir> <!-- File to upload --> <includes>maven-example-project.jar</includes> <!-- Output directory (server side) --> <toDir>/bin</toDir> <!--Jar is sent without compression over the net --> <optimize>false</optimize> <commands> <!-- Remove from the server the oldest file --> <command>\rm /bin/maven-example-project.jar</command> </commands> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> </project>



How to build

In order to execute build my example you have two way:

  • Maven CLI (Command Line Interface). In this case you need to install maven see here for more details. Here the instruction:

    1. Clone git repository or download the maven project

    2. Open terminal or your prompt and navigate to maven example project (you must go inside the folder)

    3. Execute the following command

       

      mvn clean install


    4. Go to "How To execute" in order to execute the program
  • Eclipse

    The following instructions are tested for Eclipse Mars (version 4.5).

    1. Clone git repository or download the maven project

    2. Start eclipse

    3. Click with the right mouse button on the root project and select "Run As" → "Maven build"
      Eclipse Java --> Run As --> Maven build

    4. Write "clean install" in "Goals" input field, then click on "Apply" and finally click on "Run"
      Eclipse Java --> Window --> Maven build

      If you want execute sonar, you will insert "sonar" in "Profiles" input field.

    5. Go to "How To execute" in order to execute the program


How to execute

  1. Open terminal or your prompt and navigate to maven example project (you must go inside the folder)
  2. Execute the following command (replace '/' with '\' if you are on windows environment)
     

    java -jar ./target/maven-test-project.jar


Happy coding ;)

Comments (1)

Topic: Maven example project for Java
Sort
0/5 (0)
Mozzo says...
Great job Fabio! Thank you for sharing!
8th August 2015 10:03am
Page 1 of 1

Add Comment

* Required information
Type the word for the number 9.
 
Enter answer:
 
I have read and understand the privacy policy. *
 
I have read and agree to the terms and conditions. *
 
 
Powered by Commentics