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

升级GWT项目至EclipseLink4.0.2后启动报javax.sql.DataSource找不到

问题背景

维护一个有10年历史的Java GWT项目,将旧版EclipseLink替换为自带Jakarta的EclipseLink 4.0.2。项目能正常编译,但在Eclipse中启动时抛出java.lang.ClassNotFoundException: javax.sql.DataSource错误。项目为Ant项目,非Maven项目。

报错堆栈

[WARN] Failed startup of context c.g.g.d.s.j.WebAppContextWithReload@3dd666d3{/,file:///home/halacs/WORK/eclipse-workspace/myproject/war/,UNAVAILABLE}{/home/halacs/WORK/eclipse-workspace/myproject/war}
java.lang.NoClassDefFoundError: javax/sql/DataSource
    at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:687)
    at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:654)
    at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:540)
    at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.findPersistenceUnitInfoInArchive(JPAInitializer.java:185)
    at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.findPersistenceUnitInfoInArchives(JPAInitializer.java:167)
    at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.findPersistenceUnitInfo(JPAInitializer.java:148)
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:191)
    at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
    at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at hu.halacs.myproject.server.filters.EntityManagerFilter.init(EntityManagerFilter.java:154)
    at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:140)
    at org.eclipse.jetty.servlet.ServletHandler.lambda$initialize$0(ServletHandler.java:731)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:755)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:379)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1449)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1414)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:910)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:288)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:524)
    at com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload.doStart(JettyLauncher.java:496)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
    at org.eclipse.jetty.server.Server.start(Server.java:423)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
    at org.eclipse.jetty.server.Server.doStart(Server.java:387)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at com.google.gwt.dev.shell.jetty.JettyLauncher.start(JettyLauncher.java:640)
    at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:636)
    at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:898)
    at com.google.gwt.dev.DevModeBase.run(DevModeBase.java:705)
    at com.google.gwt.dev.DevMode.main(DevMode.java:432)
Caused by: java.lang.ClassNotFoundException: javax.sql.DataSource
    at com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload$WebAppClassLoaderExtension.loadClass(JettyLauncher.java:422)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
    ... 39 more

解决方案

原因

EclipseLink 4.0.2基于Jakarta EE 9+规范,API包名从javax.*迁移到jakarta.*,但GWT开发模式的Jetty类加载器默认未包含JDBC相关API,且项目未引入兼容的javax.sql或Jakarta版JDBC API依赖。

解决步骤

  1. 引入JDBC API依赖
    下载jakarta.sql.jdbc-api-4.0.0.jar(与EclipseLink 4.0.2版本匹配),放到项目的lib目录下。

  2. 配置Ant构建脚本
    修改build.xml,确保该jar被加入编译和运行的类路径:

    <!-- 在javac任务中添加依赖 -->
    <javac srcdir="${src}" destdir="${build}" classpathref="project.classpath">
        <classpath>
            <pathelement location="lib/jakarta.sql.jdbc-api-4.0.0.jar"/>
        </classpath>
    </javac>
    
    <!-- 在GWT运行任务中添加依赖 -->
    <target name="gwt-run">
        <java classname="com.google.gwt.dev.DevMode" fork="true">
            <classpath>
                <pathelement location="lib/jakarta.sql.jdbc-api-4.0.0.jar"/>
                <!-- 其他已有依赖 -->
            </classpath>
        </java>
    </target>
    
  3. 更新Eclipse项目构建路径
    右键项目 → Build Path → Add External Archives,选择刚才下载的jar包,确保Eclipse能在开发模式下加载该类。

  4. 适配Persistence配置
    修改persistence.xml,适配Jakarta规范:

    <persistence xmlns="https://jakarta.ee/xml/ns/persistence"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
                 version="3.0">
        <!-- 你的持久化单元配置 -->
    </persistence>
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:48:15