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!");
}
});
}
}