retrieve pom from java maven-2

from - java spring get pom version



Obtiene la versiĆ³n de artefacto de Maven en tiempo de ejecuciĆ³n (7)

Me he dado cuenta de que en el JAR de un artefacto de Maven, el atributo project.version está incluido en dos archivos:

META-INF/maven/${groupId}/${artifactId}/pom.properties META-INF/maven/${groupId}/${artifactId}/pom.xml

¿Hay alguna forma recomendada de leer esta versión en tiempo de ejecución?


Aquí hay un método para obtener la versión de pom.properties, volviendo a obtenerla del manifiesto

public synchronized String getVersion() { String version = null; // try to load from maven properties first try { Properties p = new Properties(); InputStream is = getClass().getResourceAsStream("/META-INF/maven/com.my.group/my-artefact/pom.properties"); if (is != null) { p.load(is); version = p.getProperty("version", ""); } } catch (Exception e) { // ignore } // fallback to using Java API if (version == null) { Package aPackage = getClass().getPackage(); if (aPackage != null) { version = aPackage.getImplementationVersion(); if (version == null) { version = aPackage.getSpecificationVersion(); } } } if (version == null) { // we could not compute the version so use a blank version = ""; } return version; }


Estoy usando maven-assembly-plugin para mi paquete de maven. El uso de Apache Maven Archiver en la respuesta de Joachim Sauer también podría funcionar:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> <executions> <execution .../> </executions> </plugin>

Debido a que archiever es uno de los componentes compartidos por maven , podría ser utilizado por múltiples complementos de creación maven, que también podrían tener conflictos si se introducen dos o más complementos, incluida la configuración de archive interior.


No debería necesitar acceder a los archivos específicos de Maven para obtener la información de la versión de una biblioteca / clase determinada.

Simplemente puede usar getClass().getPackage().getImplementationVersion() para obtener la información de la versión que está almacenada en un archivo .jar MANIFEST.MF . Afortunadamente Maven es lo suficientemente inteligente. Desafortunadamente, Maven no escribe la información correcta en el manifiesto por defecto.

En su lugar, uno tiene que modificar el elemento de configuración <archive> de maven-jar-plugin para establecer addDefaultImplementationEntries y addDefaultSpecificationEntries en true , así:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> </plugin>

Idealmente, esta configuración debería incluirse en el pom la compañía u otra base-pom.

La documentación detallada del elemento <archive> se puede encontrar en la documentación del archivo Maven .


Para que esto se ejecute en Eclipse, así como en una compilación Maven, debe agregar las entradas pom addDefaultImplementationEntries y addDefaultSpecificationEntries como se describe en otras respuestas, luego use el siguiente código:

public synchronized static final String getVersion() { // Try to get version number from pom.xml (available in Eclipse) try { String className = getClass().getName(); String classfileName = "/" + className.replace(''.'', ''/'') + ".class"; URL classfileResource = getClass().getResource(classfileName); if (classfileResource != null) { Path absolutePackagePath = Paths.get(classfileResource.toURI()) .getParent(); int packagePathSegments = className.length() - className.replace(".", "").length(); // Remove package segments from path, plus two more levels // for "target/classes", which is the standard location for // classes in Eclipse. Path path = absolutePackagePath; for (int i = 0, segmentsToRemove = packagePathSegments + 2; i < segmentsToRemove; i++) { path = path.getParent(); } Path pom = path.resolve("pom.xml"); try (InputStream is = Files.newInputStream(pom)) { Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder().parse(is); doc.getDocumentElement().normalize(); String version = (String) XPathFactory.newInstance() .newXPath().compile("/project/version") .evaluate(doc, XPathConstants.STRING); if (version != null) { version = version.trim(); if (!version.isEmpty()) { return version; } } } } } catch (Exception e) { // Ignore } // Try to get version number from maven properties in jar''s META-INF try (InputStream is = getClass() .getResourceAsStream("/META-INF/maven/" + MAVEN_PACKAGE + "/" + MAVEN_ARTIFACT + "/pom.properties")) { if (is != null) { Properties p = new Properties(); p.load(is); String version = p.getProperty("version", "").trim(); if (!version.isEmpty()) { return version; } } } catch (Exception e) { // Ignore } // Fallback to using Java API to get version from MANIFEST.MF String version = null; Package pkg = getClass().getPackage(); if (pkg != null) { version = pkg.getImplementationVersion(); if (version == null) { version = pkg.getSpecificationVersion(); } } version = version == null ? "" : version.trim(); return version.isEmpty() ? "unknown" : version; }

Si su compilación de Java pone clases de destino en un lugar que no sea "objetivo / clases", entonces es posible que deba ajustar el valor de los segmentos para eliminar.


Para seguir la respuesta anterior, para un artefacto .war , descubrí que tenía que aplicar la configuración equivalente a maven-war-plugin , en lugar de maven-jar-plugin :

<plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1</version> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> </plugin>

Esto agregó la información de la versión a MANIFEST.MF en el MANIFEST.MF .jar del proyecto (incluido en WEB-INF/lib del .war )


Pasé un tiempo en los dos enfoques principales aquí y no funcionaron para mí. Estoy usando Netbeans para las compilaciones, puede que haya más allí. Tuve algunos errores y advertencias de Maven 3 con algunos constructos, pero creo que fueron fáciles de corregir. No es gran cosa.

Encontré una respuesta que parece fácil de mantener y de mantener en este artículo en DZone:

Ya tengo una subcarpeta resources / config, y nombré mi archivo: app.properties, para reflejar mejor el tipo de cosas que podemos mantener allí (como una URL de soporte, etc.).

La única advertencia es que Netbeans advierte que el IDE necesita filtrarse. No estoy seguro de dónde / cómo. No tiene ningún efecto en este punto. Tal vez haya una solución para eso si necesito cruzar ese puente. La mejor de las suertes.


Variante de Java 8 para EJB en archivo war con proyecto maven. Probado en EAP 7.0.

@Log4j // lombok annotation @Startup @Singleton public class ApplicationLogic { public static final String DEVELOPMENT_APPLICATION_NAME = "application"; public static final String DEVELOPMENT_GROUP_NAME = "com.group"; private static final String POM_PROPERTIES_LOCATION = "/META-INF/maven/" + DEVELOPMENT_GROUP_NAME + "/" + DEVELOPMENT_APPLICATION_NAME + "/pom.properties"; // In case no pom.properties file was generated or wrong location is configured, no pom.properties loading is done; otherwise VERSION will be assigned later public static String VERSION = "No pom.properties file present in folder " + POM_PROPERTIES_LOCATION; private static final String VERSION_ERROR = "Version could not be determinated"; { Optional.ofNullable(getClass().getResourceAsStream(POM_PROPERTIES_LOCATION)).ifPresent(p -> { Properties properties = new Properties(); try { properties.load(p); VERSION = properties.getProperty("version", VERSION_ERROR); } catch (Exception e) { VERSION = VERSION_ERROR; log.fatal("Unexpected error occured during loading process of pom.properties file in META-INF folder!"); } }); } }