使用Maven Launch4J生成的.exe双击无响应及类路径问题排查
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver with launch4j-maven-plugin Hey there, let's break down why you're hitting this issue and how to fix it properly. The root problem here is that your packaged EXE (and the underlying JAR) doesn't include the MySQL connector dependency, so the JVM can't find the driver class when running. Even though you added the dependency in your pom.xml, Maven's default JAR packaging doesn't bundle external dependencies—you need to configure your build to either include them in a "fat JAR" or tell launch4j where to find them.
Solution 1: Build a Fat JAR with Maven Shade Plugin
The easiest way to ensure all dependencies are included is to create a fat JAR (a single JAR containing your code plus all required libraries). Here's how to set up the maven-shade-plugin in your pom.xml:
<build> <plugins> <!-- Shade plugin to create a fat JAR --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <!-- Replace with your main class --> <mainClass>com.mycompany.insertmysql.insert</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> <!-- Keep your existing launch4j plugin --> <plugin> <groupId>com.akathist.maven.plugins.launch4j</groupId> <artifactId>launch4j-maven-plugin</artifactId> <version>2.2.1</version> <executions> <execution> <id>l4j-clui</id> <phase>package</phase> <goals> <goal>launch4j</goal> </goals> <configuration> <headerType>gui</headerType> <!-- Point to the fat JAR created by shade plugin --> <jar>${project.build.directory}/${project.build.finalName}.jar</jar> <outfile>${project.build.directory}/Project.exe</outfile> <mainClass>com.mycompany.insertmysql.insert</mainClass> </configuration> </execution> </executions> </plugin> </plugins> </build>
When you run mvn package, this will create a fat JAR with the MySQL connector included, and launch4j will wrap that JAR into your EXE. Double-clicking the EXE should now find the driver class without issues.
Solution 2: Keep Separate JARs and Configure Launch4j Classpath
If you prefer not to build a fat JAR, you can copy your dependencies to a lib directory and tell launch4j to include them in the classpath. Here's how:
- Add the
maven-dependency-pluginto copy dependencies to alibfolder:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.6.0</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>
- Update your launch4j plugin configuration to include the
libdirectory in the classpath:
<plugin> <groupId>com.akathist.maven.plugins.launch4j</groupId> <artifactId>launch4j-maven-plugin</artifactId> <version>2.2.1</version> <executions> <execution> <id>l4j-clui</id> <phase>package</phase> <goals> <goal>launch4j</goal> </goals> <configuration> <headerType>gui</headerType> <jar>${project.build.directory}/${project.build.finalName}.jar</jar> <outfile>${project.build.directory}/Project.exe</outfile> <mainClass>com.mycompany.insertmysql.insert</mainClass> <!-- Configure classpath to include lib folder --> <classPath> <mainClass>com.mycompany.insertmysql.insert</mainClass> <cp>lib/*.jar</cp> </classPath> <!-- Make sure the EXE looks for lib in the same directory --> <chdir>.</chdir> </configuration> </execution> </executions> </plugin>
After running mvn package, your target folder will have Project.exe, your main JAR, and a lib folder with the MySQL connector. Just make sure the lib folder stays in the same directory as the EXE when distributing it.
Quick Note on Driver Class Name
If you're using a newer version of MySQL Connector/J (8.0+), the driver class name has changed from com.mysql.jdbc.Driver to com.mysql.cj.jdbc.Driver. Double-check your code to make sure you're using the correct class name—this can also cause a ClassNotFoundException even if the JAR is present.
内容的提问来源于stack exchange,提问作者John Walker

