You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Micronaut项目构建GraalVM原生镜像时JAXB报错求助

问题:Micronaut GraalVM原生镜像中JAXB运行失败

将Micronaut项目构建为GraalVM原生应用,项目使用JAXB读写XML文件。直接运行或Jar包运行均正常,但通过micronaut-maven-plugin构建原生镜像后,执行XML相关逻辑时应用崩溃。

依赖配置

<!-- JAXB API only -->
<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>2.3.3</version>
</dependency>
<!-- JAXB Implementation -->
<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-impl</artifactId>
  <version>2.3.7</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>2.3.7</version>
</dependency>

报错信息

[main] ERROR io.micronaut.runtime.Micronaut - Error starting Micronaut server: Error starting HTTP server: javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NoSuchMethodException: com.sun.xml.bind.v2.ContextFactory.createContext([Ljava.lang.Class;, java.util.Map)]
io.micronaut.http.server.exceptions.HttpServerException: Error starting HTTP server: javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NoSuchMethodException: com.sun.xml.bind.v2.ContextFactory.createContext([Ljava.lang.Class;, java.util.Map)]
        at io.micronaut.servlet.engine.server.AbstractServletServer.start(AbstractServletServer.java:92)
        at io.micronaut.servlet.engine.server.AbstractServletServer.start(AbstractServletServer.java:34)
        at io.micronaut.runtime.Micronaut.lambda$start$2(Micronaut.java:81)
        at java.base@17.0.5/java.util.Optional.ifPresent(Optional.java:178)
        at io.micronaut.runtime.Micronaut.start(Micronaut.java:79)
        at io.micronaut.runtime.Micronaut.run(Micronaut.java:323)
        at io.micronaut.runtime.Micronaut.run(Micronaut.java:309)
        at fr.tas.co2m.Application.main(Application.java:29)
Caused by: java.lang.RuntimeException: javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NoSuchMethodException: com.sun.xml.bind.v2.ContextFactory.createContext([Ljava.lang.Class;, java.util.Map)]
        at fr.tas.co2m.Application$OnStartupEventListener.onApplicationEvent(Application.java:60)
        at fr.tas.co2m.Application$OnStartupEventListener.onApplicationEvent(Application.java:32)
        at io.micronaut.context.event.ApplicationEventPublisherFactory.notifyEventListeners(ApplicationEventPublisherFactory.java:262)
        at io.micronaut.context.event.ApplicationEventPublisherFactory.access$200(ApplicationEventPublisherFactory.java:60)
        at io.micronaut.context.event.ApplicationEventPublisherFactory$2.publishEvent(ApplicationEventPublisherFactory.java:229)
        at io.micronaut.context.DefaultBeanContext.publishEvent(DefaultBeanContext.java:1703)
        at io.micronaut.servlet.engine.server.AbstractServletServer.lambda$start$0(AbstractServletServer.java:88)
        at java.base@17.0.5/java.util.Optional.ifPresent(Optional.java:178)
        at io.micronaut.servlet.engine.server.AbstractServletServer.start(AbstractServletServer.java:81)
        ... 7 common frames omitted
Caused by: javax.xml.bind.JAXBException: null
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:259)
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:240)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
        at fr.tas.co2m.api.services.EquipmentRequestService.parseReprocessingInputFile(EquipmentRequestService.java:17)
        at fr.tas.co2m.api.services.InitService.startReprocessing(InitService.java:64)
        at fr.tas.co2m.Application$OnStartupEventListener.onApplicationEvent(Application.java:51)
        ... 15 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.sun.xml.bind.v2.ContextFactory.createContext([Ljava.lang.Class;, java.util.Map)
        at java.base@17.0.5/java.lang.Class.getMethod(DynamicHub.java:2227)
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:249)
        ... 22 common frames omitted

解决方案

1. 升级JAXB依赖到Jakarta EE兼容版本

当前依赖混合了旧版javax和Jakarta包,GraalVM对Jakarta 3.x+版本支持更完善。替换依赖为:

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.2</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>4.0.2</version>
    <scope>runtime</scope>
</dependency>

移除jaxb-impl依赖,jaxb-runtime已包含完整实现。

2. 添加GraalVM反射元数据

JAXB大量依赖反射,原生镜像构建时默认会裁剪未显式引用的类和方法,需手动添加元数据:

  • 方式一:使用Micronaut注解
    在JAXB实体类或创建JAXBContext的服务类上添加注解:
import io.micronaut.core.annotation.RegisterForReflection;

@RegisterForReflection(targets = {YourJaxbEntity1.class, YourJaxbEntity2.class})
public class EquipmentRequestService {
    // 业务逻辑代码
}
  • 方式二:生成自动配置文件
    运行Jar包时通过GraalVM代理生成反射配置:
java -agentlib:native-image-agent=config-output-dir=./src/main/resources/META-INF/native-image -jar your-app.jar

生成的配置文件会自动被原生镜像构建工具识别。

3. 显式指定JAXBContext工厂

避免动态查找失败,创建JAXBContext时直接指定工厂类:

import jakarta.xml.bind.JAXBContext;
import org.glassfish.jaxb.runtime.v2.JAXBContextFactory;
import java.util.HashMap;
import java.util.Map;

// ...
Map<String, Object> props = new HashMap<>();
props.put(JAXBContext.JAXB_CONTEXT_FACTORY, JAXBContextFactory.class.getName());
JAXBContext context = JAXBContext.newInstance(YourJaxbEntity.class, props);

4. 检查Micronaut Maven插件配置

确保插件启用GraalVM支持:

<plugin>
    <groupId>io.micronaut.build</groupId>
    <artifactId>micronaut-maven-plugin</artifactId>
    <version>4.2.1</version>
    <extensions>true</extensions>
    <configuration>
        <graalvm>
            <enabled>true</enabled>
        </graalvm>
    </configuration>
</plugin>

内容的提问来源于stack exchange,提问作者Shavoks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:00:04