Maven 构建环境中的 Atomikos + Jetty - 类加载器问题?

Posted

技术标签:

【中文标题】Maven 构建环境中的 Atomikos + Jetty - 类加载器问题?【英文标题】:Atomikos + Jetty in a Maven build environment - Classloader issue? 【发布时间】:2010-11-25 00:35:18 【问题描述】:

我正在处理一个包含多个 JDBC 数据源和 JTA 的项目。我使用 Maven 作为构建工具,我想在开发过程中使用 Jetty 插件 (6.1.20) 来运行应用程序。

我正在尝试将 Jetty 配置为使用 Atomikos 作为事务管理器。我正在关注Atomikos documentation from Jetty,但 Jetty 启动失败,看起来像是类加载器问题。

这是我的配置的相关位。

runtime 我的pom.xml 中的范围依赖:

<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jta</artifactId>
    <version>3.5.7</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jdbc</artifactId>
    <version>3.5.7</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>jta</artifactId>
    <version>1.1</version>
    <scope>runtime</scope>
</dependency>

我的jetty-env.xml 位于/WEB-INF(由 Jetty 自动发现):

<New id="userTxImpl" class="com.atomikos.icatch.jta.UserTransactionImp" />

<New id="tx" class="org.mortbay.jetty.plus.naming.Transaction">
    <Arg>
        <Ref id="userTxImpl" />
    </Arg>
</New>

最后tx 的实例化是失败的部分,如果我忽略它,Jetty 可以正常启动(但当然不会通过 JNDI 公开UserTransaction)。

堆栈跟踪:

    2009-09-02 18:42:18.910::WARN:  Config error at <New id="tx" class="org.mortbay.jetty.plus.naming.Transaction"><Arg>
            <Ref id="userTxImpl"/>
        </Arg></New>
2009-09-02 18:42:18.910::WARN:  Failed startup of context org.mortbay.jetty.plugin.Jetty6PluginWebAppContext@12515db/administrator,C:\workspace\administrator\src\main\webapp
java.lang.IllegalStateException: No Constructor: <New id="tx" class="org.mortbay.jetty.plus.naming.Transaction"><Arg>
            <Ref id="userTxImpl"/>
        </Arg></New> on org.mortbay.jetty.plugin.Jetty6PluginWebAppContext@12515db/administrator,C:\workspace\administrator\src\main\webapp
    at org.mortbay.xml.XmlConfiguration.newObj(XmlConfiguration.java:631)
    at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:256)
    at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:190)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.configureWebApp(EnvConfiguration.java:130)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1247)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:124)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:441)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:383)
    at org.mortbay.jetty.plugin.AbstractJettyRunMojo.execute(AbstractJettyRunMojo.java:210)
    at org.mortbay.jetty.plugin.Jetty6RunMojo.execute(Jetty6RunMojo.java:184)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:579)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:498)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegmentForProject(DefaultLifecycleExecutor.java:265)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:191)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:149)
    at org.apache.maven.DefaultMaven.execute_aroundBody0(DefaultMaven.java:223)
    at org.apache.maven.DefaultMaven.execute_aroundBody1$advice(DefaultMaven.java:304)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:1)
    at org.apache.maven.embedder.MavenEmbedder.execute_aroundBody2(MavenEmbedder.java:904)
    at org.apache.maven.embedder.MavenEmbedder.execute_aroundBody3$advice(MavenEmbedder.java:304)
    at org.apache.maven.embedder.MavenEmbedder.execute(MavenEmbedder.java:1)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:176)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:408)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:351)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:31)

这看起来像是一个类加载器问题,因为org.mortbay.jetty.plus.naming.Transaction 的构造函数采用了javax.transaction.UserTransaction,而com.atomikos.icatch.jta.UserTransactionImp 实现了javax.transaction.UserTransaction,但 Jetty 抱怨它没有合适的构造函数可供使用。

我显然在这里遗漏了一些东西,但它是什么?

谢谢!

【问题讨论】:

【参考方案1】:

和 Taylor 一样,我只是在这个完全相同的问题上浪费了几个小时。我使用 Hibernate 作为 JPA 提供程序,它在自己的 JTA User Tranaction 上有一个 Maven 依赖。一旦我排除了这种依赖关系,我就解决了这个问题。

【讨论】:

【参考方案2】:

我意识到这个问题已经得到解答,但我想用我的经验来拯救别人我刚刚经历的悲伤。

我遇到了类似的问题,但它是由 geronimo-jta 规范的版本冲突引起的。具体来说,atomikos 所依赖的那个与 jetty 使用的那个不符。我不得不从 atomikos 中排除一个,例如:

com.atomikos 交易要领全部 3.5.9 org.apache.geronimo.specs geronimo-jta_1.0.1B_spec

【讨论】:

【参考方案3】:

我认为您不应该将 JTA jar 指定为“运行时”要求,而应指定为“提供”要求。与 servlet-api 和 JMS 类似,各个实现者提供他们自己的 API 副本,并且提供 Sun jar 可以将它们搞砸。

【讨论】:

【参考方案4】:

您的部署中可能有多个 UserTransaction 类副本。如果这些是从不同的类加载器加载的,那么您最终可能会遇到这种错误。

检查 Jetty 的库是否有 UserTransaction,然后检查您的应用程序的库。您应该只有一份。

【讨论】:

对 jboss-j2ee 的间接依赖是问题所在,它带有自己的 UserTransaction。非常感谢!我以为我要疯了。

以上是关于Maven 构建环境中的 Atomikos + Jetty - 类加载器问题?的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的 Atomikos 异常 - init() 中的错误:日志已在使用中?

spring3.0+Atomikos 构建jta的分布式事务

spring3.0+Atomikos 构建jta的分布式事务

atomikos 笔记

基于spring+mybatis+atomikos+jta实现分布式事务

Maven详解及其环境配置