开发环境遇ClassNotFoundException: com.ibm.xml.xlxp2.jaxb.JAXBContextFactory求助
我之前也踩过IBM这个JAXB工厂类的坑,结合你的环境(Eclipse Mars + Ivy + Ant + JDK7/8),大概率是这几个容易忽略的点:
Ivy依赖的获取与配置问题
IBM的com.ibm.xml.xlxp2.jaxb.JAXBContextFactory属于IBM专属的JAXB实现包,这个包通常不在默认的Maven Central仓库里。首先要检查你的ivysettings.xml有没有配置IBM的官方仓库,比如:<resolvers> <ibiblio name="ibm-maven" root="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/" m2compatible="true"/> </resolvers>然后在
ivy.xml里显式引入依赖(版本号要匹配你的环境,比如对应JDK7的版本):<dependency org="com.ibm" name="xlxp2-jaxb" rev="1.1.0.20150101"/>另外可以用
ivy:report生成依赖报告,确认这个包有没有被成功拉取,有没有被其他依赖的exclude规则无意中排除了。jaxb.properties的放置位置错误
很多人会把这个文件随便丢在src根目录,但实际上它必须和你的JAXB实体类放在同一个包路径下。比如你的实体类在com.yourcompany.model,那jaxb.properties就得放在src/main/java/com/yourcompany/model/下面,内容必须是:javax.xml.bind.context.factory=com.ibm.xml.xlxp2.jaxb.JAXBContextFactory还要检查Ant的build脚本,确保编译时把这个
.properties文件同步拷贝到输出目录(比如target/classes),不然运行时classpath里找不到这个配置文件。Eclipse与Ant运行时的Classpath不一致
有时候Eclipse的Ivy容器已经加载了依赖,但Ant运行时用的是独立的classpath,没有包含IBM的JAXB包。要在build.xml里用Ivy的cachepath任务生成依赖classpath,然后在javac、java任务里引用:<ivy:cachepath pathid="project.classpath" conf="compile"/> <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="project.classpath"/>另外在Eclipse里运行程序时,检查Run Configuration的Classpath标签,确认Ivy管理的依赖库已经被添加,并且没有被JDK自带的JAXB(rt.jar里的)覆盖优先级。
JDK自带JAXB的优先级干扰
JDK7和8自带了JAXB实现,默认情况下JVM会优先加载rt.jar里的JAXB类,导致IBM的实现无法被选中。可以通过两种方式解决:- 在JVM启动参数里强制指定工厂类:
-Djavax.xml.bind.context.factory=com.ibm.xml.xlxp2.jaxb.JAXBContextFactory - 确保IBM的JAXB包在classpath的最前面,让JVM先加载它。在Ant里可以调整classpath的顺序,在Eclipse里可以调整Build Path的库顺序。
- 在JVM启动参数里强制指定工厂类:
排查类加载路径的终极方法
如果以上都没用,建议在运行程序时加上JVM参数-verbose:class,这样JVM会输出每个类的加载来源。你可以搜索JAXBContextFactory的加载记录,看它到底在尝试从哪个jar里加载,是根本没找到,还是被其他jar里的同名类覆盖了。
内容的提问来源于stack exchange,提问作者David Brossard

