#tomcat9 #jvm-arguments #javaagents #jvm-bytecode #elastic-apm
Вопрос:
Я пытаюсь запустить службу tomcat в linux с помощью агента elastic APM (java). Но каждый раз, когда я запускаю службу, получаю эти ошибки
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'"
и выход из системы-классическая версия 1.0.6
Пожалуйста, предложите решение или любые шаги, которые мне не хватает, заранее спасибо.
Обновление от kriegaex, скопировано из комментария ОП:
- Версия сервера: Сервер Apache Tomcat/7.0.106
- дата создания: 16 сентября 2020 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.
Комментарии:
1. Либо
elastic-apm-agent
изменяет версию байтjavax.servlet.GenericServlet
-кода класса (которую Tomcat компилирует с Java 8), либо ваше приложение содержит доисторическую версиюservlet-api.jar
(она не должна содержать никакой версии).2. Спасибо @PiotrP.Karwasz за ответ, я упомянул подробности ниже
Ответ №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. Странная вещь: 1. Загрузчик классов приложений Tomcat всегда ищет
javax.servlet.GenericServlet
в родительском загрузчике классов (см. исходный код ), поэтому древняя версияservlet-api.jar
, поставляемая в комплекте с приложением, игнорируется, 2.servlet-api.jar
В Tomcat 9 (поскольку вопрос помеченtomcat9
) используется байт-код версии 52 (Java 8).2. Скорее всего, операция использует гораздо более старую версию Tomcat. Например, библиотека logback-classic 1.0.6, которую он использует, относится к 2012 году. В то время JDK 7 был текущим, но, вероятно, в то время еще не все обновились, и вокруг было много библиотек Java 6. Я предполагаю, что у нас здесь какая-то ситуация с устаревшими приложениями, но ОП ничего не объяснил по этому поводу, так что это чистая спекуляция. В этом вопросе явно не хватает деталей.
3. Спасибо @kriegaex за ответ, ниже приведены подробные сведения о версии tomcat и т.д. Версия сервера: Apache Tomcat/7.0.106 Сервер построен: 16 сентября 2020 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
4. Это подтверждает kriegaex: Tomcat 7.0 был скомпилирован с Java 6. Вам необходимо обновить Tomcat до версии 8.5/9.0 или самостоятельно скомпилировать Tomcat 7.0 с более поздней версией Java.
5. Такие детали относятся к вопросу. Для этой цели существует кнопка «Редактировать». На этот раз я отредактировал ваш вопрос для вас, чтобы вы увидели, как это делается. Я также исправил ваши блоки кода и другое форматирование, а затем добавил детали из вашего комментария выше. Теперь они читаемы, а не одна длинная строка спагетти.