Apache Maven tips

6pf3cdvxjgwrucbfg7uvs895oeh-zgzqmk4_nsagfsay-oqli0c4m5mavqauwxg-kyno6l7z8ne2sklp-s3aakaslury37umomjyibet6m01fw8s4nhge2wb5f_3jycizzvjchdgfnbasirt1vrqmkfwjts8_-xtpcvgiz0ep-k5uh1flml7ii0as5gfsbs-7aadoump

 

Been using Ant & Apache Maven for years, now I seems to be immune with long nested XML and not bother writing about them anymore.

But with this attempt, I hope some tips here will be appreciated by Mrs. Google :-)

 

bs1fpdu3sroz2gcxal_46d9krks9wisc4aocy5h8mqafemf-gkatywykoyxxgabs991ucw06cn3zo9oflllxkghlfsbh4ij768djex63sxvzumy64rhda_f86mowiqviblhw2rujnqvifpm-w8wgq8hp_ygies3xlcmcazu0slwm9ybndtdkmzy91w5hcelpu2x1eg8a

.

Bundle all classes of dependent JAR files into our JAR

Given our original POM file is like this:

<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>vn.ducquoc.euler</groupId>
  <artifactId>euler</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>ProjectEuler fun</name>
  <description>See http://github.com/ducquoc/euler-fun</description>

  <dependencies>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.7</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
     <version>1.6.4</version>
   </dependency>
   <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-jdk14</artifactId>
     <version>1.6.4</version>
   </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
          <showWarnings>false</showWarnings>
        </configuration>
        <!--<version>2.3.2</version>-->
      </plugin>
    </plugins>
  </build>
</project>

When Maven build is invoked (like “mvn clean install” ) , it will produce a JAR file, which contains only classes of that project. So when to use it we have to include other dependencies (JAR files) in to the classpath; otherwise it will be either a NoClassDefFoundError or a ClassNotFoundException.

To avoid such trivial time waste, we can include the necessary classes to the newly created JAR. There are several ways to do that, my traditional approach is  to use maven-assembly-plugin :

<build>
  <plugins>
    <!-- to bundle all classes of dependent JAR files -->
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
          <manifest>
            <mainClass>vn.ducquoc.euler.EulerMain</mainClass>
          </manifest>
        </archive>
      </configuration>
      <executions>
        <execution>
          <id>make-assembly</id>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <!-- . . . -->
  </plugins>
</build>

Now the build will output a NAME-jar-with-dependencies.jar file !

.

Bundle necessary classes of dependent JAR files into our JAR

Given our original POM file is like above, my new approach is to use maven-shade-plugin, which is solely designed for this purpose.

<!-- to bundle necessary classes of dependent JAR files -->
 <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>1.5</version>
   <executions>
     <execution>
       <phase>package</phase>
       <goals>
         <goal>shade</goal>
       </goals>
       <configuration>
         <transformers>
           <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
             <mainClass>vn.ducquoc.euler.EulerMain</mainClass>
           </transformer>
         </transformers>
         <!--<shadedArtifactAttached>true</shadedArtifactAttached>-->
       </configuration>
     </execution>
   </executions>
 </plugin>

.

That’s it. There are still some other Maven plugins which can serve the purpose (like “onejar”, “jarjar”, … ) , yet shade is enough :-)

 

.

[OffTopic]

For Clojure, leiningen has the built-in uberjar command

$ lein uberjar

[/OffTopic]

 

.

IDE (Eclipse/IDEA/…) can utilize the editor/view to edit Maven POM, exclude dependencies, or set the “Run/Debug” configuration easily…

 

 

UPDATED 2018:

I just added a simple Maven repository, using GitHub raw:

https://github.com/ducquoc/legacy_m2_repo

 

<repository>
    <id>legacy-releases-temp-repository</id>
    <url>https://github.com/ducquoc/legacy_m2_repo/raw/master/release</url>
    <!--<url>https://raw.github.com/ducquoc/legacy_m2_repo/master/release</url>-->
</repository>

 

 

./.

 

 

About DucQuoc.wordpress.com

A coder, content creator, and a proud father of 2 princesses.
This entry was posted in Coding. Bookmark the permalink.

8 Responses to Apache Maven tips

  1. [ERROR] Failed to execute goal org.codehaus.enunciate:maven-enunciate-plugin:1.25:assemble (default) on project hudson-rest-api: Execution default of goal org.codehaus.enunciate:maven-enunciate-plugin:1.25:assemble failed: A required class was missing while executing org.codehaus.enunciate:maven-enunciate-plugin:1.25:assemble: com/sun/mirror/apt/AnnotationProcessorFactory

    ==> Work-around for maven-enunciate-plugin issue with Java 7:

    http://jira.codehaus.org/browse/ENUNCIATE-603?focusedCommentId=302322#comment-302322

    hope this helps,

  2. Some tests encounter OutOfMemoryError when using maven-compiler-plugin?

    Solution 1: set environment variable MAVEN_OPTS
    + DOS (Windows): set without using quote
    set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=384m
    + Bash (Linux): export the env var
    export MAVEN_OPTS=”-Xmx512m -XX:MaxPermSize=128m”

    Solution 2: configure the Compiler plugin and test plugin (surefire/failsafe) :

    org.apache.maven.plugins
    maven-surefire-plugin
    ${maven-surefire-plugin.version}

    once
    -Xmx1024m -XX:MaxPermSize=512m

    maven-compiler-plugin
    ${maven-compiler-plugin.version}

    1.6
    1.6
    1024m
    128m
    true

    (or use the latest stable version of the plugin)

  3. Pingback: Why Maven 3 | DucQuoc's Blog

  4. Some tips to reduce build time with Maven:

    1/ Skip tests: by -DskipTests=true or -Dmaven.test.skip=true

    2/ Comment out unnecessary plugins in POM.xml: For example, with Cirrus build we can comment out the enunciate plugin (just comment out the docs is enough)

    3/ Use maven 3 instead of maven 2. (In general maven 3 build faster 20%-30%)

    4/ Setup the frequently used build command to a script (.bat file), or utilize IDE to remember that with one click (build Maven as… or Run/Debug as…)

  5. Pingback: Logging best practices | DucQuoc's Blog

  6. As of Java 8 (2014), the javadoc may be more strict, so we have to disable that doclint with param -Xdoclint:none .


    org.apache.maven.plugins
    maven-javadoc-plugin
    2.8.1

    -Xdoclint:none

    -Xdoclint:none

    (see : http://blog.joda.org/2014/02/turning-off-doclint-in-jdk-8-javadoc.html )
    .

    The FindBugs 2.x also does not work with Java 8, so we have to upgrade the maven-findbugs-plugin version to 3.0.0+ as well :


    org.codehaus.mojo
    findbugs-maven-plugin
    <!--2.4.0-->
    3.0.1

    (see: https://issues.jboss.org/browse/JBDS-3053 )

  7. The old tip “one-jar” , with “spring-boot” maven plugin update:

    Executable Jar with Apache Maven

    Besides, hibernate-jpamodelgen with “maven-processor-plugin” is another alternative to jpa-schema-maven-plugin:

    Basic Java EE with Apache Maven

    Lombok maven plugin :

    lombok with maven

    (notably “delombok” for maven build)

Leave a comment