47 votes

Comment lire le fichier manifeste d'une application web fonctionnant sous Apache Tomcat ?

J'ai une application web qui contient un fichier manifeste, dans lequel j'écris la version actuelle de mon application lors d'une tâche de compilation par ant. Le fichier manifest est créé correctement, mais lorsque j'essaie de le lire pendant l'exécution, j'obtiens des effets de bord étranges. Mon code pour lire le manifeste est à peu près le suivant :

    InputStream manifestStream = Thread.currentThread()
                                 .getContextClassLoader()
                                 .getResourceAsStream("META-INFFFF/MANIFEST.MF");
    try {
        Manifest manifest = new Manifest(manifestStream);
        Attributes attributes = manifest.getMainAttributes();
        String impVersion = attributes.getValue("Implementation-Version");
        mVersionString = impVersion;
    }
    catch(IOException ex) {
        logger.warn("Error while reading version: " + ex.getMessage());
    }

Lorsque j'attache eclipse à tomcat, je vois que le code ci-dessus fonctionne, mais il semble obtenir un fichier manifest différent de celui que j'attendais, ce que je peux dire parce que la version ant et le timestamp de construction sont tous deux différents. Ensuite, j'ai mis "META-INFFFF" dans ce fichier, et le code ci-dessus fonctionne toujours ! Cela signifie que je lis un autre manifeste, pas le mien. J'ai aussi essayé

this.getClass().getClassLoader().getResourceAsStream(...)

Mais le résultat est le même. Quelle est la bonne façon de lire le fichier manifest à l'intérieur d'une application web fonctionnant sous tomcat ?

Editar : Merci pour les suggestions faites jusqu'à présent. Il convient également de noter que j'ai am Je lance tomcat en mode autonome à partir de la ligne de commande, puis je m'attache à l'instance en cours d'exécution dans le débogueur d'Eclipse. Cela ne devrait pas faire de différence, n'est-ce pas ?

0 votes

La réponse de @PascalThivent est la bonne. Ajoutez une gestion des exceptions dans le cas où votre MANIFEST n'existe pas (ie.:IDE) et ce devrait être A1.

0 votes

Cette méthode universelle m'a aidé : [ [stackoverflow.com/a/29103019/3158918]](http://stackoverflow.com/a/29103019/3158918])

91voto

Pascal Thivent Points 295221

Peut-être que vos effets secondaires viennent du fait que presque toutes les jarres incluent un MANIFEST.MF et que vous n'obtenez pas le bon. Pour lire le MANIFEST.MF à partir de l'application web, je dirais :

ServletContext application = getServletConfig().getServletContext();
InputStream inputStream = application.getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(inputStream);

Veuillez noter que l'exécution de Tomcat à partir d'Eclipse n'est pas la même chose que l'exécution de Tomcat seul, car Eclipse joue avec le classloader.

0 votes

@PascalThivent Y a-t-il un moyen de faire en sorte que cela fonctionne lorsque l'on exécute tomcat dans eclipse ?

0 votes

Merci beaucoup. J'ai développé ce point dans stackoverflow.com/q/37475810/1019307 sur la façon d'entrer dans un @Service .

11voto

javadude Points 927

Un peu tard, mais cela fonctionne pour moi (appl. web en Glassfish)

Properties prop = new Properties();
prop.load(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"));
System.out.println("All attributes:" + prop.stringPropertyNames());
System.out.println(prop.getProperty("{whatever attribute you want}"));

10 votes

Attention : suivre RFC-822 vous rencontrerez des problèmes en utilisant Properties puisque les valeurs longues sont réparties sur plusieurs lignes. Utilisateur Manifest à la place.

3voto

yegor256 Points 21737

Essayez d'utiliser jcabi-manifests qui fait tout le travail de chargement à votre place. En voici un exemple :

String version = Manifests.read("My-Version");

charges My-Version à partir de l'un des attributs MANIFEST.MF des dossiers.

Il est important de mentionner que (plus de détails sont aquí ) dans la plupart des conteneurs web, le chargeur de classe du thread actuel n'est pas le même que le chargeur de classe du contexte de la servlet. C'est pourquoi vous devez ajouter votre contexte de servlet au registre en cours d'exécution ( Plus d'informations ):

Manifests.append(servletContext);

A voir aussi : http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html

2voto

Par défaut, les chargeurs de classe s'en remettent au parent avant d'essayer de rechercher leurs propres ressources. Ainsi, si un chargeur de classe parent a un manifeste disponible, c'est ce que vous obtiendrez. En fait, les serveurs d'applications ne font pas nécessairement cela, afin de permettre aux applications de surcharger les versions des bibliothèques. De plus, les chargeurs de classe peuvent avoir plusieurs pots et donc plusieurs manifestes.

Il peut être en mesure d'obtenir l'URL de l'une de vos ressources au nom unique. Ouvrez une connexion. Lancez la connexion vers JarURLConnection . Obtenir le JarFile . Chargez le manifeste à partir de là. Il se peut que cela ne fonctionne pas, en particulier si Tomcat fait exploser la guerre.

[Mise à jour] Bien sûr, le fichier war lui-même n'est pas sur le classpath. Le classpath aura quelque chose comme WEB-INF/lib/( .jar| .zip) et WEB-INF/classes/. L'obtention d'une ressource à partir de la base de données ServletContext devrait fonctionner.

Meilleure solution : Faire quelque chose de différent :)

1voto

david a. Points 2969

Je ne sais pas s'il existe une façon "officielle" de le lire, mais si le fichier MANIFEST.MF ne peut pas être correctement chargé en tant que ressource, pourquoi ne pas essayer de dériver son chemin d'accès à partir d'un "ServletContext.getRealPath()" sur un chemin d'accès web défini dans votre application ?

Une autre solution qui me vient à l'esprit est d'écrire la version de l'application à un autre endroit (un fichier de propriétés dans WEB-INF/classes) par ant pendant la construction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X