Java8通过JNLP启动Swing应用报SubstanceLookAndFeel类未找到错误
问题根本原因分析
NoClassDefFoundError的直接诱因是下层的ClassNotFoundException,说明JNLP的类加载器完全找不到org.jvnet.substance.SubstanceLookAndFeel类。你已经确认substance-lite-4.3.jar在部署路径中,且同构建包在Java 6环境、Eclipse Java 8环境都能正常运行,说明问题只出在Java 8下JNLP运行环境的专属校验规则上。
核心触发原因
从Java 7 Update 51版本开始,Oracle对JNLP(Java Web Start)启动的应用引入了严格的安全校验机制,Java 8默认全部启用这些规则,而Java 6无相关限制、本地运行也不会触发这些校验,刚好匹配你遇到的场景:
- 规则1:所有通过JNLP加载的JAR包,必须在
META-INF/MANIFEST.MF文件中声明Permissions属性,属性值必须和JNLP中<security>标签的配置一致。你在JNLP中配置了<all-permissions/>,则所有JAR的清单文件中必须包含Permissions: all-permissions属性,否则JNLPClassLoader会直接拒绝加载该JAR。 - 规则2:所有签名JAR的签名算法不能是MD2、MD5、SHA-1等弱哈希算法,否则也会被JNLPClassLoader拦截,不会加入类路径。
你使用的substance-lite-4.3.jar是2009年前后发布的老版本,发布时上述安全规则还未推出,它的清单文件中没有Permissions相关配置,且如果是官方签名的版本,用的也大概率是旧的弱签名算法,因此在Java 8的JNLP环境下会被直接拦截不加载,自然找不到对应的类。
验证与解决方法
- 快速验证:打开客户端的Java控制面板,将安全等级调整为最低,同时将你的应用部署域名添加到「例外站点列表」,重启JNLP启动程序,如果可以正常运行即可确认是上述安全规则触发的问题。
- 正式修复:给所有第三方JAR(包括substance-lite-4.3.jar)重新打包,在每个JAR的MANIFEST.MF中添加如下配置:
Permissions: all-permissions Codebase: * Application-Name: 你的应用名称
之后使用SHA-256及以上强度的签名算法,用可信证书(或者测试用自签名证书,导入到客户端的信任库中)重新签名所有JAR即可。
- 可选优化:如果后续不需要兼容Java 6,也可以将Substance升级到支持Java 8的更高版本,避免老版本的兼容性问题。
内容的提问来源于stack exchange,提问作者Atul Rai
相关产品推荐
相关产品推荐

