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 :-)
.
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>
./.
[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,
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)
Pingback: Why Maven 3 | DucQuoc's Blog
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…)
Pingback: Logging best practices | DucQuoc's Blog
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 )
Some new plugins which may be interesting:
Front-end Maven plugin:
https://github.com/eirslett/frontend-maven-plugin
JPA Schema plugin:
https://github.com/divinespear/jpa-schema-maven-plugin
The old tip “one-jar” , with “spring-boot” maven plugin update:
Besides, hibernate-jpamodelgen with “maven-processor-plugin” is another alternative to jpa-schema-maven-plugin:
Lombok maven plugin :
(notably “delombok” for maven build)