J'ai besoin de lire le Manifest
fichier, qui a livré ma classe, mais quand j'utilise:
getClass().getClassLoader().getResources(...)
J'obtiens le MANIFEST
premier .jar
chargé dans le Java Runtime.
Mon application fonctionnera à partir d'une applet ou d'un webstart,
donc je n'aurai pas accès à mon propre .jar
fichier, je suppose.
Je veux en fait lire l' Export-package
attribut du .jar
qui a démarré Felix OSGi, afin que je puisse exposer ces paquets à Felix. Des idées?
java
osgi
manifest.mf
apache-felix
Houtman
la source
la source
Réponses:
Vous pouvez faire l'une des deux choses suivantes:
Appelez
getResources()
et parcourez la collection d'URL renvoyée, en les lisant comme des manifestes jusqu'à ce que vous trouviez le vôtre:Vous pouvez essayer de vérifier s'il
getClass().getClassLoader()
s'agit d'une instance dejava.net.URLClassLoader
. La majorité des chargeurs de classe Sun sont, y comprisAppletClassLoader
. Vous pouvez ensuite le lancer et appelerfindResource()
ce qui a été connu - pour les applets, au moins - pour renvoyer directement le manifeste nécessaire:la source
Vous pouvez d'abord trouver l'URL de votre classe. S'il s'agit d'un JAR, vous chargez le manifeste à partir de là. Par exemple,
la source
classPath.replace("org/example/MyClass.class", "META-INF/MANIFEST.MF"
getSimpleName
supprime le nom de classe externe. Cela fonctionne pour les classes internes:clazz.getName().replace (".", "/") + ".class"
.Vous pouvez utiliser à
Manifests
partir de jcabi-manifestes et lire n'importe quel attribut de l'un des fichiers MANIFEST.MF disponibles avec une seule ligne:La seule dépendance dont vous avez besoin est:
Consultez également ce billet de blog pour plus de détails: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
la source
<logger name="com.jcabi.manifests" level="OFF"/>
J'avoue d'emblée que cette réponse ne répond pas à la question initiale, celle de pouvoir généralement accéder au Manifeste. Cependant, si ce qui est vraiment nécessaire est de lire l'un des nombreux attributs Manifest "standard", la solution suivante est beaucoup plus simple que celles publiées ci-dessus. J'espère donc que le modérateur le permettra. Notez que cette solution est en Kotlin, pas en Java, mais je m'attendrais à ce qu'un portage vers Java soit trivial. (Bien que j'admette que je ne connais pas l'équivalent Java de ".`package`".
Dans mon cas, je voulais lire l'attribut "Implementation-Version" donc j'ai commencé avec les solutions données ci-dessus pour obtenir le flux puis le lire pour obtenir la valeur. Pendant que cette solution fonctionnait, un collègue examinant mon code m'a montré un moyen plus simple de faire ce que je voulais. Notez que cette solution est en Kotlin, pas en Java.
Notez encore une fois que cela ne répond pas à la question initiale, en particulier "Export-package" ne semble pas être l'un des attributs pris en charge. Cela dit, il existe un myPackage.name qui renvoie une valeur. Peut-être que quelqu'un qui comprend cela plus que moi peut dire si cela renvoie la valeur que l'affiche originale demande.
la source
String implementationVersion = MyApplication.class.getPackage().getImplementationVersion();
Je pense que le moyen le plus approprié d'obtenir le manifeste pour tout bundle (y compris le bundle qui a chargé une classe donnée) est d'utiliser l'objet Bundle ou BundleContext.
Notez que l'objet Bundle permet également
getEntry(String path)
de rechercher des ressources contenues dans un bundle spécifique, plutôt que de rechercher le chemin de classe complet de ce bundle.En général, si vous voulez des informations spécifiques aux bundles, ne vous fiez pas aux hypothèses concernant les chargeurs de classes, utilisez simplement les API OSGi directement.
la source
Le code suivant fonctionne avec plusieurs types d'archives (jar, war) et plusieurs types de classloaders (jar, url, vfs, ...)
la source
clz.getResource(resource).toString()
avoir des contre-obliques?Le moyen le plus simple est d'utiliser la classe JarURLConnection:
Parce que dans certains cas,
...class.getProtectionDomain().getCodeSource().getLocation();
donne le chemin avecvfs:/
, cela doit donc être traité en plus.la source
Vous pouvez utiliser getProtectionDomain (). GetCodeSource () comme ceci:
la source
getCodeSource
peut revenirnull
. Quels sont les critères pour que cela fonctionne? La documentation n'explique pas cela.DataUtilities
importé? Cela ne semble pas être dans le JDK.Pourquoi incluez-vous l'étape getClassLoader? Si vous dites "this.getClass (). GetResource ()", vous devriez obtenir des ressources relatives à la classe appelante. Je n'ai jamais utilisé ClassLoader.getResource (), bien que d'un rapide coup d'œil à la documentation Java, il semble que vous obtiendrez la première ressource de ce nom trouvée dans n'importe quel chemin de classe actuel.
la source
class.getResource("myresource.txt")
essaiera de charger cette ressource à partir decom/mypackage/myresource.txt
. Comment allez-vous utiliser cette approche pour obtenir le manifeste?la source
cl.getResourceAsStream("META-INF/MANIFEST.MF")
.classLoader.getResource(..)
eturl.openStream()
est totalement hors de propos et sujet aux erreurs car il essaie de faire la même chose que leclassLoader.getResourceAsStream(..)
fait.ClassLoader classLoader = cl.getClassLoader(); return new Manifest(classLoader.getResourceAsStream("/META-INF/MANIFEST.MF"));
J'ai utilisé la solution d'Anthony Juckel mais dans le MANIFEST.MF, la clé doit commencer par des majuscules.
Donc mon fichier MANIFEST.MF contient une clé comme:
Mykey: valeur
Ensuite, dans l'activateur ou dans une autre classe, vous pouvez utiliser le code d'Anthony pour lire le fichier MANIFEST.MF et la valeur dont vous avez besoin.
la source
J'ai cette solution étrange qui exécute des applications de guerre dans un serveur Jetty intégré, mais ces applications doivent également fonctionner sur des serveurs Tomcat standard, et nous avons des propriétés spéciales dans le manfest.
Le problème était que quand dans Tomcat, le manifeste pouvait être lu, mais quand dans la jetée, un manifeste aléatoire était ramassé (qui manquait les propriétés spéciales)
Sur la base de la réponse d'Alex Konshin, j'ai proposé la solution suivante (le flux d'entrée est ensuite utilisé dans une classe Manifest):
la source