Atlassian Maven插件中使用EasyWSDL解析WSDL时出现com.sun.org.apache.xalan.internal.xsltc.trac包NoClassDefFoundError问题求助
我来帮你梳理下这个问题,你遇到的情况在Atlassian插件这类OSGi环境里其实挺常见的——核心原因是OSGi的模块化类加载机制和普通JVM完全不同,JDK内置的com.sun开头内部包默认不会被OSGi框架导出,所以即使你在pom里配置了<import-package>,插件也找不到这个包。下面给你几个可行的解决方案,按推荐优先级排序:
方案一:改用公开的Xalan库(最稳妥)
com.sun.org.apache.xalan.internal属于JDK内部API,Oracle官方不推荐直接依赖,而且不同JDK版本可能有兼容性问题。更稳妥的方式是引入公开的Xalan依赖,完全避开JDK内部实现:
- 在pom.xml中添加Xalan的依赖:
<dependency> <groupId>xalan</groupId> <artifactId>xalan</artifactId> <version>2.7.2</version> <!-- 可替换为最新稳定版 --> </dependency>
- 修改OSGi导入配置,替换成公开的Xalan包(在Atlassian插件的
<instructions>节点下):
<build> <plugins> <plugin> <groupId>com.atlassian.maven.plugins</groupId> <artifactId>maven-jira-plugin</artifactId> <!-- 对应你的插件类型,比如confluence-plugin --> <configuration> <instructions> <Import-Package> org.apache.xalan.*, <!-- 保留你原本需要的其他包配置 --> </Import-Package> </instructions> </configuration> </plugin> </plugins> </build>
这样插件会使用你引入的Xalan库,而非JDK内部的实现,从根源上避免了OSGi类路径的问题。
方案二:让OSGi系统bundle导出目标包
如果你必须使用JDK内部的Xalan实现,可以通过JVM启动参数,强制OSGi框架的系统bundle导出com.sun.org.apache.xalan.internal.xsltc.trax包:
在Atlassian应用的启动脚本(比如setenv.sh或setenv.bat)中添加以下参数:
-Dorg.osgi.framework.system.packages.extra=com.sun.org.apache.xalan.internal.xsltc.trax
这个参数会告诉OSGi框架把这个内部包加入到系统bundle的导出列表中,之后你的插件配置的<import-package>就能正常解析到这个包了。
方案三:使用OSGi动态导入包
如果上面两种方式都无法生效,可以尝试用OSGi的动态导入特性,让插件在运行时动态查找这个包:
修改Atlassian插件的<instructions>配置:
<instructions> <DynamicImport-Package> com.sun.org.apache.xalan.internal.xsltc.trax </DynamicImport-Package> <!-- 保留你原本的Import-Package配置 --> </instructions>
动态导入会跳过启动时的包依赖检查,在运行时尝试加载目标包,不过这种方式可能存在启动顺序或兼容性风险,建议作为最后手段。
为什么单元测试正常?
单元测试是在普通JVM环境下运行的,类加载是全局的,JDK内部包默认都能被访问到;但运行在OSGi环境中,每个bundle只能访问自己显式导入的包,以及系统bundle导出的包,这就是为什么单元测试没问题但运行时出错。
内容的提问来源于stack exchange,提问作者SylverK

