mavenmaven-3maven-assembly-pluginmaven-jar-plugin

maven create zip with jar and some more files


I do not understand maven. Better use ant, but... I've managed to create jar (with, or without dependencies), I've managed to copy bat runner script close to jar but now i want to create zip with this jar and this bat. So i use assembly plugin and get BUUUM!!!! CADAAAM! In my configuration it happens so, that it executes parallel to jar packaging. I wrote assembly file:

    <assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>jg</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/classes</directory>
            <outputDirectory>/123</outputDirectory>
            <excludes>
                <exclude>assembly/**</exclude>
                <exclude>runners/**</exclude>
            </excludes>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
</assembly>

Then, I bound maven-assembly-plugin:

<plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2.1</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
                <inherited>false</inherited>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>by.dev.madhead.lzwj.Main</mainClass>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                    <descriptors>
                            <descriptor>src/main/resources/assembly/assembly.xml</descriptor>
                            <!-- <descriptorRef>jar-with-dependencies</descriptorRef> -->
                    </descriptors>
                </configuration>
            </execution>
        </executions>
    </plugin>

Now I get this in ./target:

  1. runner.bat
  2. jar_without_dependencies.jar (it is from maven-jar-plugin, right?)
  3. jar_without_dependencies.jar

And the third angers me. It contains:enter image description here And the 123 directory contains:enter image description here

As you see, I get jar with unpacked dependencies, EXCLUDED DIRS!!!!, and with dir 123, which is actually what I want (Oh! assembly plugin did that!!!).

I want to get jar with dependencies and correct manifest with classpath. As an option i want jar with unpacked dependencies (I know about <unpack>false</unpack> in assembly, but cannot get it work). I want to change /123 to / and get NORMAL JAR WITHOUT EXCLUDED FILES!!! I want two separate tasks to build jar and zip (is it done with profiles in maven??) As in ant, i would wrote something like this:

    <target name="jar_with_deps" depends-on="compile">
        <jar>
            here i copy classes (excluding some dirs with runner script), and build manifest
        </jar>
        <copy>
            copy bat file from src/main/resources/runner/runner.bat
        </copy>
    </target>
    <target name="zip" depends-on="jar_with_deps">
        <zip>
            Get jar from previous target, get runner.bat. Put them in zip
        </zip>
    </target>

Excuse me, if I am too expressive, but I am really angry with this implicit behavior. I am really stuck with this.


Solution

  • You have two options to achieve your goal:

    1. option: Create two assembly descriptors, one for jar with dependencies and one for zip. Zip takes the newly created jar.

    2. option: Create two more modules in your project: first modules shades all dependencies into one jar (or attach a shaded jar along with your main jar, save another module), have the second module depend on it and suck in that jar in your assembly. Your done.

    Depending on the size and structure of your project, I would go for the safe way: option 2. This one is guaranteed to have the correct build and dependencies order. Option 1 violates the maven way somewhat.