Eclipse IDE运行正常,Maven构建后Shaded Jar报NoClassDefFoundError
问题现象
IDE中运行正常:
Maven构建成功:
程序在IDE内运行正常,Maven构建也能顺利完成,其他同方式构建的程序均可正常运行,但打开生成的Shaded Jar文件时,抛出如下错误:
Exception in Application start method Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: com/sun/javafx/scene/control/skin/ButtonSkin at io.github.palexdev.materialfx.controls.MFXButton.createDefaultSkin(MFXButton.java:351) at javafx.scene.control.Control.doProcessCSS(Control.java:897)Caused by: java.lang.ClassNotFoundException: com.sun.javafx.scene.control.skin.ButtonSkin ... 21 moreException in thread "main" java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195) Caused by: java.lang.NoClassDefFoundError: com/sun/javafx/scene/control/skin/ButtonSkin at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1013) at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) Caused by: java.lang.ClassNotFoundException: com.sun.javafx.scene.control.skin.ButtonSkin ... 21 more Exception in thread "main" java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.lang.NoClassDefFoundError: com/sun/javafx/scene/control/skin/ButtonSkin at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174) ... 1 more Caused by: java.lang.ClassNotFoundException:com.sun.javafx.scene.control.skin.ButtonSkin ajava.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 48 more
项目目录结构
danielproject ├───src │ ├───main │ ├───java │ │ ├───com │ │ │ │ └───prajan │ │ │ │ └───danielproject │ │ │ └───DBConnection │ │ └───resources │ │ └───danielproject
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> <groupId>com.prajan</groupId> <artifactId>danielproject</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.glavo.materialfx</groupId> <artifactId>materialfx</artifactId> <version>11.13.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>15.0.1</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>15.0.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>com.prajan.danielproject.Launcher</mainClass> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.prajan.danielproject.Launcher</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Launcher类代码
package com.prajan.danielproject; public class Launcher { public static void main(String[] args) { Main.main(args); } }
问题原因及解决办法
原因分析
错误提示找不到com.sun.javafx.scene.control.skin.ButtonSkin,这个类属于JavaFX的内部私有API,JavaFX 11及后续版本中,这类内部API默认不会被打包到Shaded Jar中。而MaterialFX组件依赖了该内部类,导致运行时出现类缺失。同时,当前POM中的JavaFX未指定平台分类器,Maven仅下载基础Jar包,不包含平台相关的实现类,进一步加剧了类缺失问题。
解决步骤
- 为JavaFX依赖添加平台分类器
JavaFX是分平台的,需根据运行系统(Windows/Mac/Linux)添加对应分类器,以Windows为例修改POM:
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>15.0.1</version> <classifier>win</classifier> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>15.0.1</version> <classifier>win</classifier> </dependency>
若需跨平台,可通过Maven Profiles配置不同平台的分类器。
- 调整maven-shade-plugin配置
升级插件版本并添加规则,确保JavaFX内部类和模块信息被正确打包:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.prajan.danielproject.Launcher</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.JavaFXRuntimeModuleTransformer"/> </transformers> <filters> <filter> <artifact>*:*</artifact> <includes> <include>com/sun/javafx/**</include> <include>module-info.class</include> </includes> </filter> </filters> </configuration> </execution> </executions> </plugin>
- 修正Launcher启动方式
按照JavaFX 11+标准方式启动应用:
package com.prajan.danielproject; import javafx.application.Application; public class Launcher { public static void main(String[] args) { Application.launch(Main.class, args); } }
确保Main类继承自javafx.application.Application。
- 重新构建项目
执行以下Maven命令清理并重新打包:
mvn clean package
之后运行生成的Shaded Jar文件即可。
内容的提问来源于stack exchange,提问作者user19485562
相关产品推荐
相关产品推荐

