简体   繁体   中英

Maven Launch4j Plugin - how to configure to exclude jars used by the .exe?

I'm developing an app that takes some arguments, sends some data to a server, and receives a response. It will only be called by another app and only uses CLI interface. Its dependencies are resolved by Maven. I need to package it into an .exe(legacy reasons). Also, one of the dependencies of my app uses some Bouncy Castle jars, which cannot be packaged normally with Maven assembly plugin because they lose their signatures.

As a solution, it has been suggested to me in another question that I use Maven's Launch4j plugin to both exclude the BC jars and build the exe. However, I can't for the life of me figure out how to configure it correctly. I don't even know where to begin to look for the way to exclude the BC jars and I have no idea how to cope with the classpath-related quirks of the plugin. The plugin's readme is too sparse a documentation for my limited grasp on Maven.

The POM as it currently is neither builds an .exe, nor gives any error message, making pinpointing the error that much harder. The size of the .jar in /target is the same as it was before, hinting that the build process does not seem to be any different from what it was before the plugin was added.

Could someone please have a look at the POM and suggest some improvement to make the app build as intended? Any help, especially an explanation of why the incorrect parts were changed the way they were, would be greatly appreciated.

Current POM:

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.10</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.akathist.maven.plugins.launch4j</groupId>
                <artifactId>launch4j-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>l4j-clui</id>
                        <phase>package</phase>
                        <goals>
                            <goal>launch4j</goal>
                        </goals>
                        <configuration>
                            <dontWrapJar>true</dontWrapJar>
                            <headerType>console</headerType>
                            <jar>eet-demo-maven-1.0-SNAPSHOT-eet-sender.jar</jar>
                            <outfile>target\EETSender.exe</outfile>
                            <errTitle></errTitle>
                            <cmdLine></cmdLine>
                            <chdir>.</chdir>
                            <priority>normal</priority>
                            <downloadUrl>http://java.com/download</downloadUrl>
                            <supportUrl></supportUrl>
                            <stayAlive>true</stayAlive>
                            <restartOnCrash>true</restartOnCrash>
                            <manifest></manifest>
                            <icon></icon>
                            <singleInstance>
                                <mutexName>EETMutex</mutexName>
                                <windowTitle></windowTitle>
                            </singleInstance>
                            <classpath>
                                <mainClass>cz.tomasdvorak.eetdemo.Main</mainClass>
                                <postCp>\lib\bcprov-jdk15on-1.55.jar;\eet-demo-maven-1.0-SNAPSHOT-eet-sender.jar;\eet-demo-maven-1.0-SNAPSHOT.jar</postCp>
                            </classpath>
                            <jre>
                                <path></path>
                                <bundledJre64Bit>false</bundledJre64Bit>
                                <bundledJreAsFallback>false</bundledJreAsFallback>
                                <minVersion>1.6.0_1</minVersion>
                                <maxVersion></maxVersion>
                                <jdkPreference>preferJre</jdkPreference>
                                <runtimeBits>64/32</runtimeBits>
                            </jre>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>cz.tomasdvorak.eetdemo.Main</mainClass>
            </manifest>
        </archive>
        <descriptors>
            <descriptor>assembly.xml</descriptor>
         </descriptors>
    </configuration>
</plugin>

        </plugins>
    </build>

    <groupId>cz.tomasdvorak</groupId>
    <artifactId>eet-demo-maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.github.todvora</groupId>
            <artifactId>eet-client</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

</project>

assembly.xml:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>eet-sender</id>
    <formats>
        <format>.jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/package</directory>
            <outputDirectory>/target</outputDirectory>
            <includes>
                <include>*.exe</include>
            </includes>
            <excludes>
                <exclude>org/bouncycastle/*.*</exclude>
            </excludes>
        </fileSet>
    </fileSets>
</assembly>

Now then, what would be the proper configuration to ensure that at the end, there is an .exe which when ran with the correct arguments will execute its intended functionality?

As you told the problem with BouncyCastle is that is signed with a oracle issued certificate in order that it can work as a JCE provider.

Then you've to avoid to warp the bcprov.jar jar (this is the jar which include the JCE provided and its mandatory to be signed) inside a fat jar with all dependencies, because this way it breaks the BouncyCastle JCE jar signature.

So the thing is probably to avoid to warp the bc-prov.jar into jar-with-dependencies and and told install4j to load the jars from a folder as a classpath resource of your java execution.

To do so do the follow:

Add <dontWrapJar>true</dontWrap> and also use:

<classpath>
    <mainClass>cz.tomasdvorak.eetdemo.Main</mainClass>
    <postCp>\lib\to\yourBc\bc-prov.jar;lib\to\yourJar\eet-demo-maven-1.0-SNAPSHOT-eet-sender.jar</postCp>
</classpath>

To make sure that your eet-demo-maven-1.0-SNAPSHOT-eet-sender.jar not include the BouncyCastle JCE jar; you must change your pom.xml to make maven-assembly-plugin to point to your assembly.xml :

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>cz.tomasdvorak.eetdemo.Main</mainClass>
            </manifest>
        </archive>
        <descriptors>
            <descriptor>/path/to/assembly.xml</descriptor>
         </descriptors>
    </configuration>
</plugin>

And then in your assembly.xml try to exclude BouncyCastle provider classes:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>eet-sender</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
     <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
            <excludes>
                <exclude>org.bouncycastle:bcprov-jdk15on</exclude>
            </excludes>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/package</directory>
            <outputDirectory>/target</outputDirectory>
            <includes>
                <include>*.exe</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>

Note that this assembly.xml works basically as <descriptorRef>jar-with-dependencies</descriptorRef> but excluding org.bouncycastle:bcprov-jdk15on artifact which comes as a dependency for your com.github.todvora:eet-client . This way you will have a fat jar with all dependencies excluding the BouncyCastle provider, which must be loaded separately then in the classpath execution for launch4j.

I hope that this way it works.

After some experimenting to try out Michael-O's suggestion, I have arrived to a pom that performs as required. Build with "mvn package". The result is the desired .exe along with all the dependency jars in the target folder. Having them separated by in a lib folder would be a more standard and elegant solution, but this is a really simple app and I'm on a tight schedule, so I'm just going to leave it as it is. The winner is:

    <?xml version="1.0" encoding="UTF-8"?>
<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>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.10</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.akathist.maven.plugins.launch4j</groupId>
                <artifactId>launch4j-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>l4j-clui</id>
                        <phase>package</phase>
                        <goals>
                            <goal>launch4j</goal>
                        </goals>
                        <configuration>
                            <dontWrapJar>true</dontWrapJar>
                            <headerType>console</headerType>
                            <jar>eet-demo-maven-1.0-SNAPSHOT.jar</jar>
                            <outfile>target\EETSender.exe</outfile>
                            <errTitle></errTitle>
                            <cmdLine></cmdLine>
                            <chdir>.</chdir>
                            <priority>normal</priority>
                            <downloadUrl>http://java.com/download</downloadUrl>
                            <supportUrl></supportUrl>
                            <stayAlive>true</stayAlive>
                            <restartOnCrash>true</restartOnCrash>
                            <manifest></manifest>
                            <icon></icon>
                            <singleInstance>
                                <mutexName>EETMutex</mutexName>
                                <windowTitle></windowTitle>
                            </singleInstance>
                            <classpath>
                                <mainClass>cz.tomasdvorak.eetdemo.Main</mainClass>
                            </classpath>
                            <jre>
                                <path></path>
                                <bundledJre64Bit>false</bundledJre64Bit>
                                <bundledJreAsFallback>false</bundledJreAsFallback>
                                <minVersion>1.6.0_1</minVersion>
                                <maxVersion></maxVersion>
                                <jdkPreference>preferJre</jdkPreference>
                                <runtimeBits>64/32</runtimeBits>
                            </jre>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>cz.tomasdvorak.eetdemo.Main</mainClass>
            </manifest>
        </archive>
        <descriptors>
            <descriptor>assembly.xml</descriptor>
         </descriptors>
    </configuration>
</plugin>

</plugins>
    </build>

     <groupId>cz.tomasdvorak</groupId>
    <artifactId>eet-demo-maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.github.todvora</groupId>
            <artifactId>eet-client</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

</project>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM