使用javax.xml.bind.Unmarshaller解析简单XML字符串抛出IllegalAccessError
问题根因
- 类加载冲突+类名重名:你启用的OpenLiberty的
webProfile-8.0和jaxws-2.2特性本身已经内置了JAXB 2.2版本的API和实现,而你在Maven中额外引入了jaxb-api 2.3.1,导致应用中存在两个版本的JAXB API,分别由不同的类加载器加载(服务器公共类加载器加载内置的2.2版本,应用类加载器加载你打包的2.3.1版本)。
你定义的实体类刚好名为Name,和OpenLiberty内置JAXB实现中的某个非公开内部类重名,JAXB在运行时生成反序列化逻辑时,错误加载了服务器类加载器中的Name类,该类和你应用中定义的com.my.model.Name不属于同一个类加载上下文,因此抛出IllegalAccessError。修改类名后避开了重名问题,因此可以正常运行。 - XmlAttribute命名空间配置错误:你给
lang属性指定的命名空间值为xml不符合规范,xml前缀对应的标准命名空间为http://www.w3.org/XML/1998/namespace,错误的命名空间配置会导致反序列化时lang属性无法正常注入。
修复方案
- 首先调整Maven依赖,将你引入的
jaxb-api的scope改为provided,避免和服务器内置的JAXB实现冲突:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency>
- 修正
lang属性的命名空间配置:
@XmlAttribute(name = "lang", namespace = "http://www.w3.org/XML/1998/namespace") public String lang;
- 如果你需要保留
Name作为类名,可以在创建JAXBContext时明确指定当前应用的类加载器,避免加载到服务器内置的重名类:
JAXBContext jaxbContext = JAXBContext.newInstance(Name.class.getName(), Name.class.getClassLoader());
内容的提问来源于stack exchange,提问作者Michi-2142
相关产品推荐
相关产品推荐

