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

嵌入式Tomcat服务器添加jaxb-core依赖后触发FileNotFoundException的解决方法

嵌入式Tomcat启动时FileNotFoundException(jaxb-api.jar找不到)

问题背景

我正在开发一个基于JSP Servlet的嵌入式Tomcat应用,添加了指定的Maven依赖后,启动主程序时抛出了FileNotFoundException,提示找不到C:\Users\testuser\.m2\repository\com\sun\xml\bind\jaxb-core\2.2.11\jaxb-api.jar。

异常堆栈信息:

C:\Users\testuser.m2\repository\com\sun\xml\bind\jaxb-core\2.2.11\jaxb-api.jar
java.io.FileNotFoundException: C:\Users\testuser.m2\repository\com\sun\xml\bind\jaxb-core\2.2.11\jaxb-api.jar (系统找不到指定的文件)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.(ZipFile.java:225)
at java.util.zip.ZipFile.(ZipFile.java:155)
at java.util.jar.JarFile.(JarFile.java:166)
at java.util.jar.JarFile.(JarFile.java:130)
at org.apache.tomcat.util.compat.JreCompat.jarFileNewInstance(JreCompat.java:221)
at org.apache.tomcat.util.scan.JarFileUrlJar.(JarFileUrlJar.java:65)
at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:49)
at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:383)
at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:318)
at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:270)
at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:233)
at org.apache.jasper.servlet.TldScanner.scanJars(TldScanner.java:262)

使用的Maven依赖(pom.xml):

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>${tomcat.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>${tomcat.version}</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

主应用启动代码:

package launch;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.StandardRoot;
import java.io.File;

public class Main {
    public static void main(String[] args) throws Exception {
        String webappDirLocation = "src/main/webapp/";
        Tomcat tomcat = new Tomcat();
        //The port that we should run on can be set into an environment variable
        //Look for that variable and default to 8080 if it isn't there.
        String webPort = System.getenv("PORT");
        if(webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }
        tomcat.setPort(Integer.valueOf(webPort));

        StandardContext ctx = (StandardContext) tomcat.addWebapp("", new File(webappDirLocation).getAbsolutePath());
        System.out.println("configuring app with basedir: " + new File("./" + webappDirLocation).getAbsolutePath());

        // Declare an alternative location for your "WEB-INF/classes" dir
        // Servlet 3.0 annotation will work
        File additionWebInfClasses = new File("target/classes");
        WebResourceRoot resources = new StandardRoot(ctx);
        resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));
        ctx.setResources(resources);

        tomcat.enableNaming();
        tomcat.getConnector();
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
        tomcat.getServer().await();
    }
}

解决办法

我之前也碰到过这个问题,本质是Tomcat的JarScanner在扫描类路径时,错误地试图从jaxb-core的Jar包目录里找jaxb-api.jar——但实际上jaxb-api是一个独立的依赖,并不是jaxb-core的一部分。下面是几个可行的修复方案:

1. 显式添加jaxb-api依赖

既然Tomcat需要这个Jar,直接把它加入pom.xml即可,版本和jaxb-core保持一致:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.11</version>
</dependency>

添加后重新执行mvn clean install,Maven会自动下载这个依赖到本地仓库,Tomcat就能找到它了。

2. 让Tomcat跳过扫描jaxb-core相关Jar

如果你的应用不需要JAXB功能,或者不想额外添加依赖,可以配置Tomcat的JarScanner跳过扫描jaxb-core的Jar。修改你的Main类,在创建StandardContext之后添加以下代码:

// 获取当前上下文的Jar扫描器
StandardJarScanner jarScanner = (StandardJarScanner) ctx.getJarScanner();
// 设置跳过扫描jaxb-core的Jar
jarScanner.setSkipJars("jaxb-core-2.2.11.jar");
// 或者用通配符匹配所有版本的jaxb-core
// jarScanner.setSkipJars("jaxb-core-*.jar");

这样Tomcat就不会去扫描这个Jar,自然也就不会触发找不到文件的异常了。

3. 清理并重新下载Maven依赖

有时候是本地Maven仓库里的jaxb-core依赖损坏了,导致扫描时出错。执行以下命令清理本地仓库并重新拉取所有依赖:

mvn clean install -U

-U参数会强制Maven更新依赖,确保本地仓库里的Jar包都是完整且正确的。

4. 升级JAXB版本(可选)

2.2.11是比较老旧的版本,可能存在依赖结构的问题。你可以尝试升级到更高的稳定版本,比如2.3.x系列,这样能避免一些旧版本的兼容性问题:

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.3.8</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 17:27:38