Publié par
Il y a 10 années · 6 minutes · Java / JEE

JConsole et WebLogic 9

JConsole est un outil disponible à partir du JDK 5.0 qui repose sur l’API JMX pour afficher et suivre les métriques d’une machine virtuelle Java.
Les différentes catégories sont :

  • L’état de la mémoire et des garbages collections.
  • Les threads, liste et activité, comme sur un Thread Dump.
  • Les chargement des classes .
  • Les suivi et la gestion des MBeans.
  • Des informations générales sur la JVM (ClassPath, Library Path, Argument de la JVM, …).

Il existe deux façons de connecter une JConsole sur une machine virtuelle Java 5 :

En local

Le mode local nécessite que la JConsole et la machine virtuelle soient sur la même machine. Il suffit alors d’ajouter au démarrage de la machine virtuelle la propriété : -Dcom.sun.management.jmxremote.
Note : A partir du JDK 6, cette propriété est positionnée par défaut, donc toutes les JVM pourront être monitorées ‘Out Of the Box’.

L’exécutable de la JConsole est situé dans <JAVA_HOME>/bin. Au démarrage, la JConsole affiche l’ensemble des JVM accessibles.

A distance

JMX définit le protocole RMI comme protocole d’échange. Par défaut, on considère qu’il existe deux implémentations de RMI :

  • JRMP (Java Remote Method Protocol)
  • IIOP (Internet Inter-Orb Protocol)

Le serveur d’applications BEA Weblogic propose une implémentation supplémentaire (et plus performante), le protocole T3.

La suite de ce billet détaille la configuration à mettre en place pour chacun des trois protocoles, et les avantages et inconvénients de chacun.

JRMP

Pour accéder à une JVM par JRMP, il faut ajouter les propriétés suivantes :

[CODE]
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
[/CODE]

Note : Les paramètres com.sun.management.jmxremote.ssl=false et com.sun.management.jmxremote.authenticate=false introduisent une large faille de sécurité sur la JVM (ni authentification, ni cryptage des données échangées). La mise en place d’une authentification est possible en définissant une liste d’utilisateurs dans le fichier <Java_Home>/jre/lib/management/jmxremote.password. Tout est détailé sur ‘Luis-Miguel Alventosa’s Blog’ : Authentication and Authorization in JMX RMI connectors. Le cryptage par SSL est possible mais très lourd à mettre en place (génération de certificats)

Avec la JConsole, il existe alors deux moyens de se connecter :

  • Soit par l’onglet ‘Remote’ en précisant le nom ou l’adresse IP de la machine et le port spécifié par la propriété com.sun.management.jmxremote.port.
  • Soit par l’onglet ‘Advanced’ en spécifiant l’URL suivante : service:jmx:rmi:///jndi/rmi://192.168.199.131:7001:12345/jmxrmi. La construction de l’URL est en partie expliquée dans la javadoc de la classe JMXServiceURL. Les champs User Name et Password restent vides.

Avantages : Simplicité de mise en œuvre et de connexion (Onglet ‘Remote’).
Inconvénient : Sécurité.

IIOP

Java RMI Over IIOP permet de s’interfacer avec les ORB, spécifiés par CORBA (Common Object Request Broker Architecture). Les serveurs d’applications certifiés J2EE se doivent de supporter le protocole IIOP (RMI/IIOP). Pour connecter une JConsole sur un serveur d’applications WebLogic 9.x avec le protocole IIOP, il est nécessaire d’activer ce protocole et de déclarer un utilisateur afin de s’authentifier. La procédure est décrite ici. La JVM nécessite d’être démarrée avec l’option :

-Dcom.sun.management.jmxremote

Dans la JConsole, il est faut utiliser l’onglet ‘Advanced’ et indiquer l’url suivante :
service:jmx:rmi:///jndi/iiop://192.168.199.131:7001/weblogic.management.mbeanservers.runtime

Avantage : –
Inconvénients : Compliqué à paramétrer, complexité liée au protocole IIOP.

T3

J2EE 1.0 n’imposait pas le support d’IIOP. BEA a alors mis au point T3, un protocole propriétaire plus performant. Depuis, le protocole T3 est le protocole par défaut pour accéder aux différents objets distants hébergés sur un serveur d’applications WebLogic. Puisque T3 implémente RMI, il est possible de brancher la JConsole à une JVM avec T3.

Tout d’abord il faut :

  • Ajouter le jar weblogic.jar au lancement de la JConsole.
  • Indiquer les ‘ClientProviders’ fournis par BEA (propriété jmx.remote.protocol.provider.pkgs).

[CODE]
set JAVA_HOME=D:\bea\alsb21\jdk150_04
%JAVA_HOME%\bin\jconsole.exe
-J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;D:\bea\alsb21\weblogic91\server\lib\weblogic.jar;%JAVA_HOME%\lib\tools.jar
[/CODE]

Pour se connecter, il faut utiliser le mode ‘advanced’ et indiquer :

  • JMXURL : service:jmx:t3://192.168.199.131:7001/jndi/weblogic.management.mbeanservers.runtime
  • UserName : weblogic
  • Password : ********

Il faut que l’utilisateur possède les droits d’administration.

JMX Connection Failed

Après activation des logs et analyse j’ai remarqué que les credentials (UserName et Password) n’étaient pas transférés au moment du lookup de l’objet MBeanServer. Pour y remédier, il suffit d’écrire un nouveau ‘ClientProvider’ du protocole T3 qui va effectuer cette manipulation : transfert de la propriété ‘jmx.remote.credentials’ vers ‘java.naming.security.principal’ et ‘java.naming.security.credentials’.

package fr.xebia.jmx.remote.t3;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.management.remote.JMXConnector;
import javax.management.remote.JMXServiceURL;

public class ClientProvider extends
		weblogic.management.remote.t3.ClientProvider {

  public JMXConnector newJMXConnector(JMXServiceURL jmxserviceurl, Map map)
		throws IOException {		
	Map newMap = checkCredentials(map);
	return super.newJMXConnector(jmxserviceurl, newMap);	
  }

  @SuppressWarnings("unchecked")
  private Map checkCredentials(Map map) {
	if (!map.containsKey("java.naming.security.principal")
			&& !map.containsKey("java.naming.security.credentials")) {
		if (map.containsKey("jmx.remote.credentials")) {
			Map newMap = new HashMap();
			newMap.putAll(map);
			String[] cred = (String[]) map.get("jmx.remote.credentials");
			newMap.put("java.naming.security.principal", cred[0]);
			newMap.put("java.naming.security.credentials", cred[1]);
			return newMap;
		}
	}
	return map;
  }
}

Il faut ensuite ajuster la ligne de commande (ajout de la classe fr.xebia.jmx.remote.t3.ClientProvider au classpath et modification de la propriété jmx.remote.protocol.provider.pkgs).

[CODE]
set JAVA_HOME=D:\bea\alsb21\jdk150_04
%JAVA_HOME%\bin\jconsole.exe
-J-Djmx.remote.protocol.provider.pkgs=fr.xebia.jmx
-J-Djava.class.path=t3jconsole.jar,%JAVA_HOME%\lib\jconsole.jar;D:\bea\alsb21\weblogic91\server\lib\weblogic.jar;%JAVA_HOME%\lib\tools.jar
[/CODE]

Avec les mêmes informations rentrées dans l’onglet ‘Advanced’, vous serez maintenant connecté à votre serveur d’applications WebLogic 9 avec la JConsole en utilisant le protocole T3.

Avantage : Pas de paramétrage supplémentaire (l’activation du protocole IIOP et la déclaration du user IIOP nécessitent un redémarrage du serveur).
Inconvénient : Il est impossible de brancher la JConsole avant que le serveur soit ‘Running’, donc pas de suivi du démarrage du serveur.

Conclusion

La JConsole permet rapidement de voir le comportement mémoire, le CPU et les traitements d’un serveur d’applications. Désormais, pensez à ajouter le ‘-Dcom.sun.management.jmxremote’ sur l’ensemble de vos JVM 5.0 afin de permettre un diagnostic rapide en cas de problème.

Références

10 réflexions au sujet de « JConsole et WebLogic 9 »

  1. Publié par Eamonn McManus, Il y a 10 années

    Excellent article !

    Je rajouterais juste qu’il existe un autre moyen de préciser le ClientProvider à utiliser, à savoir les conventions jar de « service providers » documentées à . Ça évite d’avoir à spécifier la propriété jmx.remote.protocol.provider.pkgs, au coût d’une manip supplémentaire au moment de la création du jar.

    Le fait que le ClientProvider par défaut de T3 ne reconnaisse pas jmx.remote.credentials me semble être un bug — est-ce que BEA est au courant ?

  2. Publié par bmoussaud, Il y a 10 années

    Merci du compliment. Je ne savais pas que le ClientProvider pouvait utiliser le mécanisme de ServiceProvider. C’est pourtant écrit dans la JavaDoc ! J’ai regardé les versions de Weblogic 9.1 et 9.2, aucun des jars fournis ne package le META-INF/services, même dans le jar client jmx (wljmxclient).

    Si on regarde le code example suivant:
    * JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES est indiqué explicitement.
    * La propriété ‘jmx.remote.credentials’ n’est pas utilisée mais Context.SECURITY_PRINCIPAL et Context.SECURITY_CREDENTIALS. Le code du ClientProvider assigne ‘jmx.remote.credentials’ avec les valeurs Context.SECURITY_PRINCIPAL et Context.SECURITY_CREDENTIALS.

    Or ce n’est pas exactement le code utilisé par la JConsole. C’est meme plutot l’inverse, ‘JConsole will pass the user name and password as client credentials as authentication to the RMI connector server by setting the « jmx.remote.credentials » property to these values in the environment map for establishing the connection’

    On peut donc en conclure que c’est un bug chez BEA. Il faudrait à l’occasion que je le remonte au support.

  3. Publié par Nérisson, Il y a 9 années

    Le parametre à ajouter ne serait pas plutôt
    -J-Djmx.remote.protocol.provider.pkgs=fr.xebia.jmx.remote

  4. Publié par Benoit Moussaud, Il y a 9 années

    @Nérisson
    Tout a fait exact ! je vais corriger l’article.

  5. Publié par Bernard, Il y a 8 années

    Merci pour cet article très utile. Deux questions additionnelles :
    – Le « bug » weblogic sur les credentials et le protocole T3 est-il résolu ?
    – Est-ce que quelqu’un a testé avec Weblogic 10 ?

    Et une petite correction : l’URL si on passe par JRMP serait plutôt : service:jmx:rmi:///jndi/rmi://192.168.199.131:12345/jmxrmi (pas de port 7001)

  6. Publié par bmoussaud, Il y a 8 années

    @Bernard
    Je ne sais pas si le problème a été corrigé en weblogic 10, mais les informations indiquées dans l’article devrait rester valables
    Pour ce qui concerne l’url, si tu regarde dans la section ‘JRMP’,elle est correcte.

  7. Publié par jlamande, Il y a 8 années

    Bonjour à tous,

    mais pour moi, le problème d’authentification est malheureusement toujours présent en 10.3
    Je ne comprends pas comment l’article que Benoit référence peut fonctionner.

    Mon script (DOS):
    set CLASSPATH=%JAVA_HOME%\lib\jconsole.jar;%WLS_HOME%\lib\weblogic.jar;%JAVA_HOME%\lib\tools.jar;
    %JAVA_HOME%\bin\jconsole -J-Djava.class.path=%CLASSPATH% -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug

    Erreur obtenue toujours la même sans le patch :
    java.lang.SecurityException: Anonymous attempt to get to a JNDI resource

  8. Publié par Benoit Moussaud (Xebia), Il y a 8 années

    Bonjour
    Je pense que vous avez oublié de mettre un ‘username’ et un ‘password’ dans jconsole. J’ai effectué le test avec votre ligne de commande sur un domaine 10.3 et je me suis connecté sans problèmes:
    * JMXURL : service:jmx:t3://localhost:7001/jndi/weblogic.management.mbeanservers.runtime
    * UserName : weblogic
    * Password : ********

    Si vous voulez cependant pouvoir effectuer des lookup anonymes, il faut modifier la configuration du domaine Domain –> Security –> General : Anonymous Admin Lookup Enabled: on

  9. Publié par nboheas, Il y a 5 années

    Salut Benoit (private joke : comme on se retrouve!)

    Je me permet de te signaler qu’il faut ajouter en plus des paramètres -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false pour la connexion en JRMP le paramètre : -Djava.rmi.server.hostname= car sinon l’appel à la console jmx n’est dispo qu’en local.

    A plus !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *