Necesito leer el Manifest
archivo, que entregó mi clase, pero cuando uso:
getClass().getClassLoader().getResources(...)
Obtengo el MANIFEST
primero .jar
cargado en Java Runtime. Supongo que
mi aplicación se ejecutará desde un applet o un inicio web,
por lo que no tendré acceso a mi propio .jar
archivo.
De hecho, quiero leer el Export-package
atributo del .jar
que inició Felix OSGi, para poder exponer esos paquetes a Felix. ¿Algunas ideas?
java
osgi
manifest.mf
apache-felix
Houtman
fuente
fuente
Respuestas:
Puedes hacer una de las dos cosas:
Llame
getResources()
e itere a través de la colección devuelta de URL, leyéndolas como manifiestos hasta que encuentre la suya:Puede intentar verificar si
getClass().getClassLoader()
es una instancia dejava.net.URLClassLoader
. La mayoría de los cargadores de clase Sun son, inclusoAppletClassLoader
. Luego puede emitirlo y llamar a lofindResource()
que se conoce, al menos para los applets, para devolver el manifiesto necesario directamente:fuente
Puedes encontrar la URL de tu clase primero. Si es un JAR, entonces carga el manifiesto desde allí. Por ejemplo,
fuente
classPath.replace("org/example/MyClass.class", "META-INF/MANIFEST.MF"
getSimpleName
elimina el nombre de la clase externa. Esto funcionará para las clases internas:clazz.getName().replace (".", "/") + ".class"
.Se puede utilizar
Manifests
desde jcabi manifiestos y leer cualquier atributo de cualquiera de los archivos disponibles MANIFEST.MF con una sola línea:La única dependencia que necesita es:
Además, consulte esta publicación de blog para obtener más detalles: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
fuente
<logger name="com.jcabi.manifests" level="OFF"/>
Admitiré de antemano que esta respuesta no responde a la pregunta original, la de poder acceder en general al Manifiesto. Sin embargo, si lo que realmente se requiere es leer uno de varios atributos de Manifiesto "estándar", la siguiente solución es mucho más simple que las publicadas anteriormente. Así que espero que el moderador lo permita. Tenga en cuenta que esta solución está en Kotlin, no en Java, pero esperaría que un puerto a Java fuera trivial. (Aunque admito que no sé el equivalente Java de ".`package".
En mi caso, quería leer el atributo "Implementation-Version", así que comencé con las soluciones dadas anteriormente para obtener el flujo y luego lo leí para obtener el valor. Si bien esta solución funcionó, un compañero de trabajo que revisó mi código me mostró una manera más fácil de hacer lo que quería. Tenga en cuenta que esta solución está en Kotlin, no en Java.
Una vez más, tenga en cuenta que esto no responde a la pregunta original, en particular "Export-package" no parece ser uno de los atributos admitidos. Dicho esto, hay un myPackage.name que devuelve un valor. Quizás alguien que entiende esto más de lo que puedo comentar si eso devuelve el valor que solicita el póster original.
fuente
String implementationVersion = MyApplication.class.getPackage().getImplementationVersion();
Creo que la forma más adecuada de obtener el manifiesto para cualquier paquete (incluido el paquete que cargó una clase determinada) es usar el objeto Bundle o BundleContext.
Tenga en cuenta que el objeto Bundle también proporciona la
getEntry(String path)
búsqueda de recursos contenidos dentro de un paquete específico, en lugar de buscar en todo el classpath de ese paquete.En general, si desea información específica del paquete, no confíe en suposiciones sobre los cargadores de clases, solo use las API de OSGi directamente.
fuente
El siguiente código funciona con múltiples tipos de archivos (jar, war) y múltiples tipos de cargadores de clases (jar, url, vfs, ...)
fuente
clz.getResource(resource).toString()
tener barras invertidas?La forma más fácil es usar la clase JarURLConnection:
Porque en algunos casos
...class.getProtectionDomain().getCodeSource().getLocation();
da camino convfs:/
, por lo que esto debe manejarse adicionalmente.fuente
Puede usar getProtectionDomain (). GetCodeSource () de esta manera:
fuente
getCodeSource
puede devolvernull
. ¿Cuáles son los criterios para que esto funcione? La documentación no explica esto.DataUtilities
importa? No parece estar en el JDK.¿Por qué incluye el paso getClassLoader? Si dice "this.getClass (). GetResource ()", debería obtener recursos relativos a la clase que realiza la llamada. Nunca he usado ClassLoader.getResource (), aunque de un vistazo rápido a los Documentos de Java parece que eso te dará el primer recurso de ese nombre encontrado en cualquier classpath actual.
fuente
class.getResource("myresource.txt")
intentará cargar ese recurso desdecom/mypackage/myresource.txt
. ¿Cómo exactamente utilizará este enfoque para obtener el manifiesto?fuente
cl.getResourceAsStream("META-INF/MANIFEST.MF")
.classLoader.getResource(..)
yurl.openStream()
es totalmente irrelevante y propenso a errores, ya que intenta hacer lo mismo que loclassLoader.getResourceAsStream(..)
hace.ClassLoader classLoader = cl.getClassLoader(); return new Manifest(classLoader.getResourceAsStream("/META-INF/MANIFEST.MF"));
He usado la solución de Anthony Juckel pero en MANIFEST.MF la clave tiene que comenzar con mayúsculas.
Entonces mi archivo MANIFEST.MF contiene una clave como:
Mykey: valor
Luego, en el activador u otra clase, puede usar el código de Anthony para leer el archivo MANIFEST.MF y el valor que necesita.
fuente
Tengo esta extraña solución que ejecuta aplicaciones de guerra en un servidor Jetty incorporado, pero estas aplicaciones también deben ejecutarse en servidores Tomcat estándar, y tenemos algunas propiedades especiales en el Manfest.
El problema era que cuando estaba en Tomcat, el manifiesto podía leerse, pero cuando estaba en el embarcadero, se recogía un manifiesto aleatorio (que no tenía las propiedades especiales)
Basado en la respuesta de Alex Konshin, se me ocurrió la siguiente solución (el flujo de entrada se usa en una clase de Manifiesto):
fuente