Problèmes de chargeur de classe - Comment déterminer les versions de bibliothèque (fichiers jar) chargées

StackOverflow https://stackoverflow.com/questions/139534

  •  02-07-2019
  •  | 
  •  

Question

Je viens de résoudre un autre * je-dis-moi-utilisant-cette-version-de-une-bibliothèque-mais apparemment-mon-serveur-d'application-a-déjà-chargé-un-ancien- version-of-this-library- * (soupir).

Quelqu'un connaît-il un bon moyen de vérifier (ou de contrôler) si votre application a accès à tous les fichiers JAR appropriés ou aux versions de classe chargées?

Merci d'avance!

[P.S. Une très bonne raison pour commencer à utiliser la architecture de module OSGi à mon avis!]

Mise à jour : Cet article a également été utile. ! Cela m'a donné un aperçu des classes chargées par le chargeur de classes de JBoss en les écrivant dans un fichier journal.

Était-ce utile?

La solution

Si vous utilisez JBoss, il existe un MBean (le référentiel de chargeur de classe iirc) dans lequel vous pouvez demander à tous les chargeurs de classe ayant chargé une classe donnée.

Si tout échoue, il y a toujours 'java -verbose: class' qui imprimera l'emplacement du fichier jar pour chaque fichier de classe en cours de chargement.

Autres conseils

Si vous avez les informations de versions appropriées dans un manifeste de fichier JAR, il existe des méthodes pour récupérer et tester la version. Pas besoin de lire manuellement le manifeste.

java.lang.Package .getImplementationVersion () et getSpecificationVersion () et isCompatibleWith () sonnent comme s'ils feraient ce que vous cherchez.

Vous pouvez obtenir le package avec this.getClass (). getPackage () entre autres.

Le javadoc de java.lang.Package ne donne pas les noms d'attributs manifestes spécifiques à ces attributs. Une recherche rapide sur Google a abouti à http: // java. sun.com/docs/books/tutorial/deployment/jar/packageman.html

Dans la version actuelle de Java, la gestion des versions de bibliothèque est un terme plutôt complexe qui s'appuie sur le bon formatage du fichier JAR avec un manifeste utile. Même dans ce cas, l’application en cours demande beaucoup de travail pour rassembler ces informations de manière utile. Le runtime de JVm ne vous aide absolument pas.

Je pense que votre meilleur choix est d'appliquer cette règle au moment de la construction, en utilisant des outils de gestion des dépendances comme Ivy ou Maven pour récupérer les versions correctes de tout.

Fait intéressant, Java 7 inclura probablement un cadre de versioning de module approprié pour ce type de choses. Non que cela vous aide en ce moment,

Je ne pense pas qu’il existe un bon moyen de vérifier cela. Et je ne suis pas sûr que tu veuilles faire ça. Ce que vous devez faire, c'est vous familiariser avec l'architecture de chargement de classes de votre serveur d'applications et comprendre comment cela fonctionne.

Une explication simplifiée de son fonctionnement est la suivante: un EJB ou une application Web recherchera d’abord une classe ou une ressource dans des bibliothèques déclarées dans son propre module (ejb-jar ou war). si la classe n'y est pas trouvée, le chargeur de classe transfère la demande au chargeur de classe parent, qui est soit une dépendance déclarée (habituellement un ejb), soit le chargeur de classe d'application chargé de charger les bibliothèques et les ressources déclarées dans le package ear. . Si la classe ou la ressource n'est toujours pas trouvée, la demande est transmise au serveur d'applications qui examinera son propre chemin de classe.

Ceci étant dit, vous devez vous rappeler qu'un module Java EE (web-app, ejb) chargera toujours les classes à partir d'un fichier jar situé dans la portée la plus proche. Par exemple, si vous empaquetez log4j v1 dans le fichier war, log4j v2 au niveau des oreilles et que vous mettez log4j v3 dans le chemin de classes de votre serveur d'applications, le module utilisera le fichier jar dans son propre module. enlever ça et il va utiliser celui au niveau de l'oreille. retirez-le et il utilisera celui du classpath du serveur d'applications. Les choses deviennent plus compliquées lorsque vous avez des dépendances complexes entre les modules.

Le mieux est de placer les bibliothèques globales d'applications au niveau de l'oreille.

Il doit y avoir un meilleur moyen que ce que je fais, mais j'ai tendance à le faire de manière très manuelle.

  1. Chaque fichier Jar doit avoir son numéro de version dans le nom du fichier (s'il ne change pas son nom).
  2. chaque application a son propre chemin de classe.
  3. Il doit y avoir une raison pour commencer à utiliser un fichier Jar mis à jour (nouvelle version). Ne changez pas simplement parce que c'est disponible, changez parce que cela vous donne les fonctionnalités dont vous avez besoin.
  4. Chaque version doit inclure tous les fichiers JAR nécessaires.
  5. Je garde une classe Version qui connaît la liste des fichiers JAR dont elle a besoin (elle est codée dans le fichier source) et peut être vérifiée au moment de l'exécution par rapport à la liste des fichiers JAR du chemin de classe.

Comme je l’ai dit, c’est manuel, mais ça marche.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top