Ce document vous guide à travers deux problèmes associés à leurs solutions liés au chargement de classes à partir de JBoss EAP/Wildfly.
Télémétrie incomplète de l'agent
Problème
Vous remarquez une télémétrie incomplète provenant d'une application utilisant JBoss EAP 7.4 (ou supérieur) ou Wildfly 23 (ou supérieur). Une télémétrie incomplète pourrait ressembler à :
- requests Web sont traduites en transactions non Web
- Votre nom de répartiteur est incorrect
Si vous définissez votre log à l'aide du niveau de log Finest
et trouvez NoClassDefFoundError
et ClassNotFoundException
traces d'appels, cela indique un problème avec le fonctionnement du chargement de classe avec JBoss EAP et Wildfly.
L'agent peut instrumenter une classe spécifique dans une application à l'aide de JBoss, mais les classes modifiées peuvent utiliser des packages et des modules qui ne sont pas reconnus par JBoss EAP/Wildfly. Le résultat est que le chargeur de classe du module de JBoss ne peut pas trouver de classes spécifiques, ce qui génèrera un NoClassDefFoundError
.
Même si votre application fonctionne toujours, les données envoyées par l'agent seront incorrectes ou incomplètes. Depuis la version 8.6 agent , l'agent Java peut faire reconnaître par JBoss certains packages en les faisant charger par le classloader système. Cela permet à l'instrumentation Wildfly/JBoss EAP de fonctionner immédiatement, mais le ClassLoader peut toujours renvoyer ClassNotFoundException
ou NoClassDefFoundError
.
Solution
Lorsque vous définissez le agent niveau de log Finest
sur, recherchez les traces d'appels contenant NoClassDefFoundError
dans votre agent fichier de log.
Voici un exemple de cette erreur apparaissant dans le package java.util.logging
même si cet exemple a été corrigé dans la version 8.6 :
2022-02-01T11:59:16,167-0800 [97709 221] com.newrelic.agent.instrumentation.ClassTransformerServiceImpl FINEST: An error was thrown from instrumentation library com.newrelic.instrumentation.servlet-2.4java.lang.NoClassDefFoundError: java/util/logging/Level at com.nr.instrumentation.servlet24.ServletHelper.setTxNameUsingServletName(ServletHelper.java:187) ~[?:?] at com.nr.instrumentation.servlet24.ServletHelper.setTransactionName(ServletHelper.java:96) ~[?:?] at javax.servlet.http.HttpServlet.service(HttpServlet.java) ~[?:?] at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[?:?] at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[?:?] at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[?:?] at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[?:?] at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) ~[?:?] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[?:?] at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[?:?] at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[?:?] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[?:?] at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[?:?] at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) ~[?:?] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68) ~[?:?] at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[?:?] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269) ~[undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78) ~[undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133) ~[undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130) ~[undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105) ~[?:?] at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530) ~[?:?] at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530) ~[?:?] at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530) ~[?:?] at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530) ~[?:?] at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249) [undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78) [undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99) [undertow-servlet-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387) [undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:841) [undertow-core-2.2.5.Final-redhat-00001.jar!/:2.2.5.Final-redhat-00001] at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) [jboss-threads-2.4.0.Final-redhat-00001.jar!/:2.4.0.Final-redhat-00001] at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) [jboss-threads-2.4.0.Final-redhat-00001.jar!/:2.4.0.Final-redhat-00001] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) [jboss-threads-2.4.0.Final-redhat-00001.jar!/:2.4.0.Final-redhat-00001] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) [jboss-threads-2.4.0.Final-redhat-00001.jar!/:2.4.0.Final-redhat-00001] at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280) [xnio-api-3.8.4.Final-redhat-00001.jar!/:3.8.4.Final-redhat-00001] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_312]Caused by: java.lang.ClassNotFoundException: java.util.logging.Level from [Module "io.undertow.servlet" version 2.2.5.Final-redhat-00001 from local module loader @7ce85af2 (finder: local module finder @316acbb5 (roots: /Users/obenmeir/AppServers/jboss-eap-7.4/modules,/Users/obenmeir/AppServers/jboss-eap-7.4/modules/system/layers/base))] at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255) ~[?:?] at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) ~[?:?] at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) ~[?:?] at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) ~[?:?] ... 22 more
Vous trouverez ci-dessous trois solutions potentielles pour cette erreur.
Correction 1 : mettez à niveau votre agent
Assurez-vous que votre agent Java est en version 8.6
ou supérieure.
Correction 2 : marquer le package à charger par le chargeur de classes système »
Étant donné que la classe java.util.logging.Level
est à l’origine de l’erreur, nous devons définir une propriété système appelée jboss.modules.system.pkgs
. Cela permet à JBoss de reconnaître toutes les classes du package java.util.logging
comme un package système. De telles classes sous le package espace de nommage seront chargées par un chargeur de classes système plutôt que par le chargeur de classes de JBoss.
Pour résoudre ce problème, définissez la propriété système en ajoutant une liste séparée par des virgules des packages Java que vous souhaitez que JBoss reconnaisse. Par exemple : Djboss.modules.system.pkgs=java.util.logging,javax.management
.
Correction 3 : configurer manuellement les modules JBoss
L’un des problèmes avec les correctifs précédents est que certains packages ne sont pas disponibles via le chargeur de classes système. Un cas ici est celui du package javax.management
. Par conséquent, votre application peut ne pas démarrer ou ne pas fonctionner correctement en raison de cas de ClassNotFoundException
.
Dans ce cas, vous devez configurer manuellement les modules JBoss concernés qui sont mentionnés dans le log de votre agent . Pour notre scénario, nous continuerons avec java.util.logging
, qui fait partie du module java.logging
. D'après la stacktrace, nous voyons que le module JBoss affecté est io.undertow.servlet
.
Nous pouvons trouver le fichier de configuration d'un module JBoss spécifique sur votre serveur JBoss en procédant comme suit :
- Allez dans le chemin relatif
modules/system/layers/base
. - Entrez le chemin du fichier en fonction du nom du module. Dans le cas de
io.undertow.servlet
, cela se traduit pario/undertow/servlet
. - Allez dans le fichier sous le chemin
main/module.xml
. Le chemin relatif complet du fichier de configurationio.undertow.servlet
estmodules/system/layers/base/io/undertow/servlet/main/module.xml
. - Dans le fichier XML, modifiez le corps de la tag
<dependencies>
à l'intérieur de la tag<module>
. Si la tag n'est pas là, ajoutez-la. - À l'intérieur de la tag
<dependencies>
, ajoutez l'élément<module name="INSERT_MODULE_NAME"/>
. Pourjava.util.logging
, l'élément devient<module name="java.logging"/>
.
Vous trouverez ci-dessous un exemple XML pour io.undertow.servlet
:
<module name="io.undertow.servlet" xmlns="urn:jboss:module:1.9"> <resources> <resource-root path="undertow-servlet-2.2.5.Final-redhat-00001.jar"/> </resources>
<dependencies> <module name="java.logging"/> <module name="javax.annotation.api"/> <module name="sun.jdk"/> <module name="javax.servlet.api"/> <module name="javax.servlet.jsp.api"/> <module name="javax.servlet.jstl.api"/> <module name="org.jboss.logging"/> <module name="io.undertow.core"/> <module name="org.jboss.xnio"/> <module name="jdk.unsupported"/> </dependencies></module>
Répétez ces étapes pour tous les modules concernés.
L'application ne démarre pas ou présente d'autres problèmes de chargement de classe
Problème
Il s'agit de la solution si votre agent Java est en version 8.6
ou supérieure et que vous utilisez l'API de gestion Jakarta/J2EE (JSR-777), mais que votre application ne parvient pas à démarrer. Dans ce instance, vous verrez des cas de ClassNotFoundException
où le nom package inclus dans la classe est javax.management.j2ee
Solution
Si vous avez mis à niveau l'agent Java vers 8.6
ou une version supérieure, votre application risque de ne pas démarrer si vous utilisez l'API de gestion Jakarta/J2EE. La solution à ce problème consiste à mettre à niveau votre agent vers 8.7
ou une version supérieure, puis à ajouter la propriété système :
-Dcom.newrelic.jboss.jsr77.fix=true
La conséquence de la définition de la propriété système sur true
est que l’agent n’étiquetera pas javax.management
comme une classe système. Par conséquent, vous aurez besoin d'une configuration supplémentaire. Suivez ces étapes :
- Modifiez le fichier XML en allant dans
modules/system/layers/base/io/undertow/servlet/main/module.xml
. - Recherchez le corps de la tag
<dependencies>
à l'intérieur de la tag<module>
. Si la tag n'est pas là, ajoutez-la. - À l'intérieur de la tag
<dependencies>
, ajoutez l'élément<module name="java.management"/>
.
Voici un exemple snippet XML pour JBoss EAP 7.4 :
<module name="io.undertow.servlet" xmlns="urn:jboss:module:1.9"> <resources> <resource-root path="undertow-servlet-2.2.5.Final-redhat-00001.jar"/> </resources>
<dependencies> <module name="javax.annotation.api"/> <module name="sun.jdk"/> <module name="javax.servlet.api"/> <module name="javax.servlet.jsp.api"/> <module name="javax.servlet.jstl.api"/> <module name="org.jboss.logging"/> <module name="io.undertow.core"/> <module name="org.jboss.xnio"/> <module name="jdk.unsupported"/> <module name="java.management"/> </dependencies></module>