【问题标题】:Manage TomEE libs loading order管理 TomEE 库加载顺序
【发布时间】:2018-10-02 00:52:59
【问题描述】:

我有一个 EJB 应用程序,目前部署在 TomEE 1.7.4 上,在 docker 容器中使用 OpenJDK 7(openjdk 7、TomEE 和我的战争)。

注意:我在 TomEE lib 文件夹中添加的 Jar 文件由应用程序重新整理,因为我在添加这些 Jar 文件后出现了一些错误。

错误日志

INFO: PersistenceUnit(name=manager1, provider=org.hibernate.jpa.HibernatePersistenceProvider) - provider time 2214ms
Apr 25, 2018 5:35:21 PM org.apache.openejb.assembler.classic.Assembler destroyApplication
INFO: Undeploying app: /usr/local/tomee/webapps/myapp
Apr 25, 2018 5:35:21 PM org.apache.catalina.core.ContainerBase removeChild
SEVERE: ContainerBase.removeChild: destroy: 
org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before_destroy]) for component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myapp]] in state [STARTING_PREP]
    at org.apache.catalina.util.LifecycleBase.invalidTransition(LifecycleBase.java:401)
    at org.apache.catalina.util.LifecycleBase.destroy(LifecycleBase.java:291)
    at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:1038)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.undeploy(TomcatWebAppBuilder.java:1537)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.undeploy(TomcatWebAppBuilder.java:1518)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.undeployWebApps(TomcatWebAppBuilder.java:762)
    at org.apache.openejb.assembler.classic.Assembler.destroyApplication(Assembler.java:1982)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:839)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:677)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1261)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1100)
    at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:130)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5472)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1091)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1980)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
    at java.lang.Thread.run(Thread.java:748)

Apr 25, 2018 5:35:21 PM org.apache.tomee.catalina.TomcatWebAppBuilder startInternal
SEVERE: Unable to deploy collapsed ear in war StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myapp]
org.apache.openejb.OpenEJBException: Creating application failed: /usr/local/tomee/webapps/myapp: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:843)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:677)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1261)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1100)
    at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:130)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5472)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1091)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1980)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
    at org.hibernate.cfg.annotations.EntityBinder.processComplementaryTableDefinitions(EntityBinder.java:973)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:824)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3845)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3799)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1412)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
    at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
    at org.apache.openejb.assembler.classic.EntityManagerFactoryCallable.call(EntityManagerFactoryCallable.java:64)
    at org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.createDelegate(ReloadableEntityManagerFactory.java:116)
    at org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.<init>(ReloadableEntityManagerFactory.java:102)
    at org.apache.openejb.assembler.classic.PersistenceBuilder.createEntityManagerFactory(PersistenceBuilder.java:154)
    at org.apache.openejb.assembler.classic.Assembler.loadPersistenceUnits(Assembler.java:982)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:741)

添加到 TomEE lib 文件夹的 Jar 列表:

  • mysql:mysql-connector-java:5.1.22
  • org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final
  • org.hibernate:hibernate-entitymanager:4.3.9.Final
  • org.hibernate:hibernate-core:4.3.9.Final
  • org.hibernate.common:hibernate-commons-annotations:4.0.5.Final
  • org.jboss:jandex:1.1.0.Final
  • org.jboss.logging:jboss-logging:3.1.3.GA
  • org.javassist:javassist:3.18.1-GA
  • antlr:antlr:2.7.7
  • dom4j:dom4j:1.6.1

虽然,我尝试在这个 docker 映像中部署其他应用程序,但每个想法都按预期工作。

【问题讨论】:

  • Dockerfile 添加了@EngineerDollery
  • 您缺少此问题的实际异常消息。进一步查看错误日志。我认为这不是 Docker 问题,您的应用由于某种原因无法部署 - 我们不知道为什么,因为该问题中缺少该信息。
  • 更复杂的是,您正在将战争部署到 webapps 目录,所以这看起来像一个 webapp,而不是 EJB 应用程序。你可否确认?如果它只是一个 web 应用程序,那么我强烈建议将其移至 spring-boot 并为自己节省多年的心痛。
  • 我查看了然后从问题中删除了您的 dockerfile。很好,最后不相关,因为这是 java/jpa 问题,而不是 docker 问题。
  • 好的,我正在部署的应用程序已经投入生产几年了,当我遇到这个问题时,我只是将部署方法更改为 dockerized。所以,改变技术或升级 JAVA、TomEE 版本都不是选项。关于这些条件我找不到更好的解决方案,如果您有任何基于这些事实的建议,请。做我的客人

标签: java hibernate ejb apache-tomee


【解决方案1】:

TLDR;您的 TomEE 版本不支持您似乎正在使用的 api。

我会升级 TomEE,这样您就可以获得对您想要使用的 API 的适当支持。其他解决方案只是解决方法,由于不受支持,可能会以多种方式中断。


再长一点的答案:

这对我来说看起来是 java 应用程序依赖问题/版本冲突:请参阅 this thread 了解类似的错误消息及其原因。您添加的依赖项取决于 javax.persistence spec 2.1,但根据堆栈跟踪,您的应用似乎使用的是较旧的 api。

您似乎想使用 Java Persistence API 2.1,即comes with Java EE 7。 Java EE 6 contains Java Persistence API 2.0.

您使用的 TomEE 版本,Apache TomEE 1.7.4,仅支持 Java EE 6 和 Persistence API 2.0,它是 last version not supporting Java EE 7

从此时起,TomEE 社区将把大部分精力集中在 TomEE 7.0.0 上,这将是第一个在 Apache Tomcat 8.x 上运行的 TomEE Java EE 7 驱动版本。

所以升级 TomEE 是有必要的。

【讨论】:

  • 是的,我排除了所有可能在我的 pom.xml 中产生冲突的依赖项。真正的问题是tomEE lib文件夹中的jars,仍然包含包含旧api的依赖项,我不知道如何忽略这些libs或强制jpa 2.1 jar覆盖它们。
  • @ZiedYaich 我认为它们包含依赖项,因为tomEE 不正式支持更新版本。由于没有支持,我不确定您是否能够在没有此类问题的情况下使该设置正常工作。
【解决方案2】:

TomEE 附带 OpenJPA 作为持久性引擎。 您可以更改为休眠,但您必须关注this guide

虽然可以解决问题,但扩展 ClassPath 是一个糟糕的解决方案。

【讨论】:

    【解决方案3】:

    我想通了,解决方法是在 TomEE bin 目录中创建一个“setenv.sh”文件,其中包含“jpa 2.1”jar 文件的 CLASSPATH。

    setenv.sh

    #!/bin/sh
    CLASSPATH=/usr/local/tomee/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar
    

    【讨论】:

    • 这是一个非常糟糕的解决方案,因为您已经将 jar 强行放到了路径上。您无法控制 TomEE 中的包优先级解决方案,这可能只是靠运气在您测试过的系统上起作用,您没有“管理”您的依赖项,您已经超出了“maven”构建和部署模型,并且您已强制重新配置服务器,使其只能为您的应用和您的应用单独工作。
    • 我怀疑您这样做是因为您已在 maven pom.xml 中将此依赖项列为可选。如果您删除范围,jar 将与您的应用正确捆绑,并且 TomEE 的类加载器将确保您的应用使用正确的 jar。
    • 好的,我正在部署的应用程序已经投入生产几年了,当我遇到这个问题时,我只是将部署方法更改为 dockerized。所以,改变技术或升级 JAVA、TomEE 版本都不是选项。关于这些条件我找不到更好的解决方案,如果您有任何基于这些事实的建议,请。告诉我
    猜你喜欢
    • 2014-05-16
    • 2012-01-24
    • 1970-01-01
    • 2012-01-01
    • 2013-12-20
    • 2011-06-02
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多