【问题标题】:Tomcat Service not starting with elastic APM java agentTomcat 服务未使用弹性 APM java 代理启动
【发布时间】:2021-08-10 13:44:26
【问题描述】:

我正在尝试使用弹性 APM 代理 (java) 在 linux 中启动 tomcat 服务。但是每次我启动服务时,都会出现这些错误

SEVERE: ContainerBase.addChild: start:
    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/mis-all-1.0.0]]
    at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1007)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:983)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:639)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1296)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:2037)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    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:745)
Caused by: java.lang.VerifyError: (class: javax/servlet/GenericServlet, method: init signature: (Ljavax/servlet/ServletConfig;)V) invokedynamic bytecode is not supported in this class file version
    at java.lang.Class.getDeclaredFields0(Native Method)
    at java.lang.Class.privateGetDeclaredFields(Class.java:2509)
    at java.lang.Class.getDeclaredFields(Class.java:1819)
    at org.apache.catalina.util.Introspection.getDeclaredFields(Introspection.java:106)
    at org.apache.catalina.startup.WebAnnotationSet.loadFieldsAnnotation(WebAnnotationSet.java:270)
    at org.apache.catalina.startup.WebAnnotationSet.loadApplicationServletAnnotations(WebAnnotationSet.java:138)
    at org.apache.catalina.startup.WebAnnotationSet.loadApplicationAnnotations(WebAnnotationSet.java:70)
    at org.apache.catalina.startup.ContextConfig.applicationAnnotationsConfig(ContextConfig.java:417)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:891)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:388)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5536)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    ... 10 more
    
May 20, 2021 5:48:15 AM org.apache.catalina.startup.HostConfig deployDirectory
SEVERE: Error deploying web application directory []
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/mis-all-1.0.0]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1011)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:983)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:639)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1296)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:2037)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    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:745)

我正在使用以下命令为 APM 代理设置环境变量

export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/app/elastic-apm-agent-1.23.0.jar"
export CATALINA_OPTS="$CATALINA_OPTS -Delastic.apm.service_name=Stage-pricing"
export CATALINA_OPTS="$CATALINA_OPTS -Delastic.apm.application_packages=org,com,com.qr.jadu"
export CATALINA_OPTS="$CATALINA_OPTS -Delastic.apm.server_url=http://ip:8200"
export CATALINA_OPTS="$CATALINA_OPTS -Delastic.apm.global_labels='env=Stage'"

和 logback-classic 版本 1.0.6

请提出解决方案或我遗漏的任何步骤,提前致谢。


kriegaex 更新,复制自 OP 的评论:

  • 服务器版本:Apache Tomcat/7.0.106 服务器
    • 建成时间:2020 年 9 月 16 日 08:33:41 UTC
    • 服务器编号:7.0.106.0 操作系统
  • 操作系统:Linux 操作系统版本:4.14.35-2047.502.4.1.el7uek.x86_64
  • 架构:amd64
  • JVM 版本:1.7.0_301-b09
  • JVM 供应商:Oracle Corporation APM
  • 服务器版本:7.12.1
  • APM 代理语言和版本:java,1.23。 apm 代理还支持 7u60+、8u40+、9、10、11。

【问题讨论】:

  • elastic-apm-agent 修改 javax.servlet.GenericServlet 类的字节码版本(Tomcat 使用 Java 8 编译)或者您的应用程序包含 servlet-api.jar 的史前版本(它不应包含任何版本)。
  • 感谢@PiotrP.Karwasz 的回复,我在下面提到了细节

标签: tomcat9 jvm-arguments javaagents jvm-bytecode elastic-apm


【解决方案1】:
Caused by: java.lang.VerifyError: (
  class: javax/servlet/GenericServlet,
  method: init
  signature: (Ljavax/servlet/ServletConfig;)V)
invokedynamic bytecode is not supported in this class file version

皮奥特是对的。您的 Elastic APM 代理 - 无论做什么 - 都会转换 void GenericServlet.init(ServletConfig) 的字节码,以利用 invokedynamic 字节码指令,而不是检查或期望它编织成的代码来自古老的 Java 版本。 Invokedynamic 是在 Java 7 中引入的,因此您的 JAR 必须包含旧版本。如果可以通过这种方式配置代理,则将其从转换中排除,或者升级 JAR,使用更新的版本或将 API 源重新编译为更新的 (Java 7+) 字节码版本。大多数代理可能更期待 Java 8+,但我不确定你的。

【讨论】:

  • 奇怪的是: 1. Tomcat的应用程序类加载器总是在父类加载器中寻找javax.servlet.GenericServlet(参见source code),所以与应用程序捆绑的一个古老版本的servlet-api.jar被忽略了, 2. Tomcat 9 中的servlet-api.jar(因为问题被标记为tomcat9)使用字节码版本52(Java 8)。
  • 很可能,OP 使用的是更旧的 Tomcat 版本。例如,他使用的 logback-classic 1.0.6 库是 2012 年的。那时,JDK 7 是当前的版本,但当时可能还不是每个人都更新了,并且周围有很多 Java 6 库。我猜,我们这里有某种遗留应用程序的情况,但是 OP 没有对此做出任何解释,所以这纯粹是猜测。这个问题显然缺乏细节。
  • 感谢@kriegaex 的回复,下面是关于tomcat等版本的详细信息。服务器版本:Apache Tomcat/7.0.106 服务器构建时间:2020 年 9 月 16 日 08:33:41 UTC 服务器编号:7.0 .106.0 操作系统名称:Linux 操作系统版本:4.14.35-2047.502.4.1.el7uek.x86_64 架构:amd64 JVM 版本:1.7.0_301-b09 JVM 供应商:Oracle Corporation APM 服务器版本:7.12.1 APM 代理语言和版本:java , 1.23 还有apm代理支持7u60+, 8u40+, 9, 10, 11这些版本的java
  • 这证实了 kriegaex:Tomcat 7.0 是使用 Java 6 编译的。您需要升级到 Tomcat 8.5/9.0 或使用更新版本的 Java 自己编译 Tomcat 7.0。
  • 这样的细节属于问题。为此,存在一个“编辑”按钮。这次我为你编辑了你的问题,所以你看看它是如何完成的。我还修复了您的代码块和其他格式,然后从您上面的评论中添加了详细信息。现在它们是可读的,而不是一根长长的意大利面条串。
猜你喜欢
  • 2021-10-23
  • 2019-06-21
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
相关资源
最近更新 更多