无需Agent在GraalVM Native Image中使用JAXB的问题排查
GraalVM Native模式下JAXB反射配置问题
问题背景
在GraalVM Native模式下执行XML编组/解编组操作时,抛出org.graalvm.nativeimage.MissingReflectionRegistrationError异常,提示SingleElementNodeProperty的构造方法未注册到运行时反射。
异常详情
JUnit Jupiter:MainTest:testToXml() MethodSource [className = 'org.acme.MainTest', methodName = 'testToXml', methodParameterTypes = ''] => org.graalvm.nativeimage.MissingReflectionRegistrationError: The program tried to reflectively invoke method public org.glassfish.jaxb.runtime.v2.runtime.property.SingleElementNodeProperty(org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl,org.glassfish.jaxb.runtime.v2.model.runtime.RuntimeElementPropertyInfo) without it being registered for runtime reflection. Add public org.glassfish.jaxb.runtime.v2.runtime.property.SingleElementNodeProperty(org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl,org.glassfish.jaxb.runtime.v2.model.runtime.RuntimeElementPropertyInfo) to the reflection metadata to solve this problem. See https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection for help. org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils.forQueriedOnlyExecutable(MissingReflectionRegistrationUtils.java:72) java.base@21.0.2/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:74) java.base@21.0.2/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) java.base@21.0.2/java.lang.reflect.Constructor.newInstance(Constructor.java:486) org.glassfish.jaxb.runtime.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:94) org.glassfish.jaxb.runtime.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:148) org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:464) org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:283) org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1115) org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:144) [...]
示例代码
public static String toXml(MyAnnotatedClass instance) { StringWriter out = new StringWriter(); JAXB.marshal(instance, out); return out.toString(); }
现有反射配置(META-INF/native-image/org.acme/issue-reproducer/reflect-config.json)
[ { "name":"org.acme.MyAnnotatedClass", "allDeclaredFields":true, "queryAllDeclaredMethods":true, "methods":[{"name":"<init>","parameterTypes":[] }, {"name":"getType","parameterTypes":[] }] } ]
Maven构建配置
<build> <plugins> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> <version>0.10.0</version> <extensions>true</extensions> <executions> <execution> <id>build-native</id> <goals> <goal>compile-no-fork</goal> </goals> <phase>package</phase> </execution> <execution> <id>test-native</id> <goals> <goal>test</goal> </goals> <phase>test</phase> </execution> </executions> </plugin> </plugins> </build>
环境与元数据加载情况
- GraalVM版本:21.0.2 CE
- native-maven-plugin 0.9.12及以上版本默认启用可达性元数据仓库,构建日志显示已加载元数据:
[INFO] [graalvm reachability metadata repository for org.glassfish.jaxb:jaxb-runtime:4.0.4]: Configuration directory not found. Trying latest version. [INFO] [graalvm reachability metadata repository for org.glassfish.jaxb:jaxb-runtime:4.0.4]: Configuration directory is org.glassfish.jaxb/jaxb-runtime/3.0.2
临时解决方案
手动将SingleElementNodeProperty添加到反射配置可解决问题,但并非理想方案:
[ { "name":"org.acme.MyAnnotatedClass", "allDeclaredFields":true, "queryAllDeclaredMethods":true, "methods":[{"name":"<init>","parameterTypes":[] }, {"name":"getType","parameterTypes":[] }] }, { "name":"org.glassfish.jaxb.runtime.v2.runtime.property.SingleElementNodeProperty", "queryAllPublicConstructors":true, "methods":[{"name":"<init>","parameterTypes":["org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl","org.glassfish.jaxb.runtime.v2.model.runtime.RuntimeElementPropertyInfo"] }] } ]
问题提问
现有配置是否已满足无需使用Agent在Native Image中使用JAXB的要求?为何仍需手动添加反射配置?
内容的提问来源于stack exchange,提问作者Christopher Chianelli
相关产品推荐
相关产品推荐

