New page: In Maven, compared to Ant, I have huge problems to configure the system to do exactly what I want. For example, I want to package my application (two my own JAR files, plus all...
New page
In [[Maven]], compared to [[Ant]], I have huge problems to configure the system to do exactly what I want. For example, I want to package my application (two my own [[JAR]] files, plus all the dependency [[JAR]]s) into a single ZIP file that everyone could download. This is not easy at all. The only tool that does something similar seems to be ''shade'' plugin. But its functionality is still far from optimal.
It seems to me that development of simple [[Java]] desktop applications is not really well supported by current [[Maven]] plugins. Packaging to a compound ZIP seemed unsupported, execution of a main method is supported, but not by official [[Apache]]'s plugin. It seems to me that [[Java]] desktop is second class citizen in [[Maven]].
On the other hand one can find tons of tools for server side. Packaging to ''WAR'' file is possible (this is almost the ZIP file requested above, and I even wanted to create ''WAR'' instead of ''ZIP'', but it does not work, it requires some ''web.xml'' file, which I obviously don't have). Execution on glashfish, grizzly, etc. is easy. All these application servers have their own plugins and thus are easy to start with.
All this leads to me following question: is [[Maven]] really ready for development of [[Java]] desktop applications? And a follow up: Why it is not?
=== It is Ready! It is Just Different. ===
Thanks to all your [[Talk:Maven|overwhelming responses]] I managed to find solution of the packaging. I can confirm that [[Maven]] can be used to package [[Java]] desktop applications. Just give up on ''shade'' and use ''assembly'' plugin. This is the configuration in my ''pom.xml'' file:
<source lang="xml">
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>all-zip.xml</descriptor>
</descriptors>
<finalName>myapp-${version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>myapp.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</source>
One also needs to create additional assembly file. In my case it is located next to the ''pom.xml'' and named ''all-zip.xml'':
<source lang="xml">
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>all</id>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
<files>
<file>
<source>target/myapp-${version}.jar<source>
<outputDirectory>/</outputDirectory>
</file>
</files>
</assembly>
</source>
And that is all. I have to admit that at the end this is much simpler than using plain [[Ant]]. In [[Ant]] it would be an enormous amount of [[XML]] code to generate the ''Class-Path'' attribute tons of ''<pathconvert>'' magic. In [[Maven]] this is for almost free (as soon as you know which plugin is the right one to use). My application now has executable main [[JAR]] and all the libraries in subfolder ''lib''. It can be executed as ''java -jar myapp-1.8/myapp-1.8.jar''. Perfect!
<source lang="bash">
myapp-1.8/myapp-1.8.jar
myapp-1.8/lib/jersey-core-1.1.0-ea.jar
myapp-1.8/lib/jsr311-api-1.1.jar
myapp-1.8/lib/jersey-server-1.1.0-ea.jar
myapp-1.8/lib/asm-3.1.jar
myapp-1.8/lib/jersey-json-1.1.0-ea.jar
myapp-1.8/lib/jettison-1.1.jar
myapp-1.8/lib/jaxb-impl-2.1.10.jar
myapp-1.8/lib/jackson-asl-0.9.4.jar
myapp-1.8/lib/org-netbeans-libs-freemarker-RELEASE67.jar
myapp-1.8/lib/org-netbeans-modules-queries-RELEASE67.jar
myapp-1.8/lib/org-openide-filesystems-RELEASE67.jar
myapp-1.8/lib/org-openide-util-RELEASE67.jar
myapp-1.8/lib/jersey-client-1.1.0-ea.jar
myapp-1.8/lib/freemarker-2.3.8.jar
</source>
I am surprised this is not one of the standard archetypes. As I wrote in [[Chapter 9]], one of the best [[API]]s is wizard. Good wizard can turn any [[API]], regardless how bad, complicated and hidden, into perfectly shining, beautiful [[star]]. [[Good Technology|Good tools]] make everything easier. Having ''Java Application Archetype'' would save me a lot of hours of googling and blogging (if I could find the archetype, of course).
==== Compare to [[Ant]] ====
Laszlo Kishalmi [[Talk:Maven|donated]] the same code in [[Ant]]:
<source lang="xml">
<copy todir="${dist.dir}/lib" flatten="true">
<fileset dir="${basedir}/lib" includes="**/*.jar"/>
</copy>
<pathconvert property="main.jar.class-path" dirsep="/" pathsep=" ">
<path><fileset dir="${dist.dir}" includes="lib/*.jar"/></path>
<map from="${dist.dir}/" to=""/>
</pathconvert>
<jar update="true" jarfile="${dist.dir}/main.jar">
<manifest>
<attribute name="Class-Path" value="${main.jar.class-path}"/>
</manifest>
</jar>
</source>
Can you feel the difference?