Java 17迁移至Jakarta包后JAXB NamespacePrefixMapper异常求助
问题解决方案
1. 依赖统一调整
Jakarta JAXB 4.x的官方实现为org.glassfish.jaxb:jaxb-runtime,必须保证它与jakarta.xml.bind-api版本完全一致,避免混用不同版本的API和实现。移除旧的com.sun.xml.bind/jaxb-impl依赖,添加如下配置:
<!-- Jakarta JAXB API --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.2</version> </dependency> <!-- GlassFish JAXB Runtime (官方实现) --> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.2</version> <scope>runtime</scope> </dependency>
2. 修正NamespacePrefixMapper相关配置
在Jakarta JAXB 4.x中,NamespacePrefixMapper的属性名和类路径已变更:
- 标准属性名:
jakarta.xml.bind.marshaller.NamespacePrefixMapper(替代原GlassFish特定属性名) - 类路径:
org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper
代码修正点
- 修改常量定义:
public static String NAMESPACE_PROPERTY = "jakarta.xml.bind.marshaller.NamespacePrefixMapper";
- 确保导入正确的类:
import org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper;
3. 完整修正后代码示例
import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Marshaller; import org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper; public class BaseMarshaller { public static String NAMESPACE_PROPERTY = "jakarta.xml.bind.marshaller.NamespacePrefixMapper"; public static String A1NAMESPACE = "a1"; public static String NO_NAMESPACE = ""; public static String NAMESPACEURI = "http://www.example.com/xmlns/a1"; private Marshaller m; public BaseMarshaller(JAXBContext jaxContext) throws JAXBException { this(jaxContext, Constants.SCHEMA_LOCATION); } public BaseMarshaller(JAXBContext jaxContext, String schemaLocation) throws JAXBException { m = jaxContext.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation); m.setProperty(NAMESPACE_PROPERTY, new NamespacePrefixMapperImpl()); } public static class NamespacePrefixMapperImpl extends NamespacePrefixMapper { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { if (NAMESPACEURI.equals(namespaceUri)) { return A1NAMESPACE; } return NO_NAMESPACE; } } }
4. 验证注意事项
- 确保所有JAXB相关导入均为
jakarta.xml.bind.*,无遗留的javax.xml.bind.*包 - 确认API与Runtime版本完全匹配,避免版本不一致导致的兼容性问题
- 必须使用Jakarta规范定义的标准属性名,原GlassFish私有属性名已不再生效
内容的提问来源于stack exchange,提问作者user3778690
相关产品推荐
相关产品推荐

