Last night I dove into Maven: The Complete Reference again with one very specific goal in mind: creating an artifact similar to what Eclipse produces when you export an executable jar with its dependencies in a directory next to it. I came up gasping for air with this solution clenched in my teeth.
The main class is a "Hello, World!" program. It prints its message through slf4j just so I'd have an excuse to bring in some dependencies. Here's the POM:
<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>com.chalcodes.fnord</groupId> <artifactId>HelloMaven</artifactId> <version>1.0</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.2</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.9</version> </dependency> </dependencies> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> </plugin> <!-- make an executable jar *without* deps --> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>fnord.Hello</mainClass> </manifest> </archive> </configuration> </plugin> <!-- assemble a zip file with the deps in lib/ --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.4</version> <configuration> <descriptors> <descriptor>assembly.xml</descriptor> </descriptors> </configuration> </plugin> </plugins> </build> </project>
And here's the assembly descriptor it references:
<assembly> <id>complete</id> <formats> <format>zip</format> </formats> <files> <file> <source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source> <destName>${project.artifactId}.${project.packaging}</destName> <fileMode>0644</fileMode> </file> </files> <dependencySets> <dependencySet> <useProjectArtifact>false</useProjectArtifact> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> </assembly>This produces a file called HelloMaven-1.0-complete.zip. It contains a directory called HelloMaven-1.0, which in turn contains the executable HelloMaven.jar and the lib/ directory full of dependencies. The classpath in the manifest of the executable jar correctly references each dependency by its relative path.
I still need to figure out how to attach the zip file to the Maven project (if that's the right term) and automatically deploy it to my repo. But I feel like the tables have turned in my war with Maven. This will make building and deploying Weapon M a breeze, not only for me but for anyone who wants to customize it.
No comments:
Post a Comment