Verziószám megjelenítése az alkalmazásban
Utoljára frissítve: 2017. szeptember 26.
Technológiák: Maven 3.5.0, Maven JAR Plugin 3.0.2, Build Number Maven Plugin 1.4
Kocka írt nem olyan régen egy posztjában arról, hogy hogyan lehet az alkalmazás verziószámát kiírni a felületre. Mivel én is nemrég csináltam meg több projektünkben is, álljon itt az én megoldásom.
Új projektjeink már Mavent használnak buildeléshez, ahol a pom.xml
tartalmazza a verziószámot.
Ez a legtöbb esetben elég is. Ez egyértelműen azonosít egy artifactot, azaz egy alkalmazást
(vagy annak moduljait). Maven használata esetén a SNAPSHOT verziószámmal rendelkező artifactból lehet több is,
de a release-elt artifactból csak egy lehet, ha egyszer kiadtuk, az már többet nem módosulhat. Javasolt
tesztelésre, élesre csakis release-elt artifactot kitenni, így egyértelműen azonosítható, így elég lesz az
azonosításra a verziószám is. Continuous delivery esetén is minden build egy potenciális release,
saját verziószámmal. Abban az esetben, ha mégis SNAPSHOT verziókat akarunk kiadni tesztelésre, érdemes
még valamilyen plusz azonosítót társítani a verziószám mellé. Ez lehet egy egyedileg
kézzel megadott érték (ekkor elég nagy a hibalehetőség), egy automatikusan növelt egész szám (ennek a tárolásával
lehetnek gondok), timestamp, verziókezelő rendszerre jellemző egyedi azonosító (pl. Subversion revision, Git commit hash), vagy egy környezeti változóban átadott érték.
Ez utóbbi például használható akkor, ha a Jenkins Continuous Integration rendszer a BUILD_NUMBER
-t
környezeti változóban adja át. (A Jenkins mellesleg átadja a verziókövető rendszerre jellemző egyedi azonosítót is, Subversion
esetén SVN_REVISION
, Git esetén GIT_COMMIT
néven.)
Mivel a META-INF/MANIFEST.MF
állomány pont ilyen információk tárolására alkalmas, érdemes oda beírni és
onnan kiolvasni.
Ahhoz, hogy a MANIFEST.MF
állományban is szerepeljen a verziószám, a következővel egészítsük ki a
pom.xml
-t.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
Ekkor a Apache Maven Archiver oldalon leírtaknak megfelelően elhelyezi a MANIFEST.MF
állományban a megfelelő bejegyzéseket, köztük az Implementation-Version
bejegyzést a projekt verziószámával.
Ezt a következőképp tudjuk kiolvasni, pl. JAR futtatása esetén a classpath-ról a getResourceAsStream()
metódussal.
Egy példa alkalmazás elérhető a GitHubon.
try (InputStream is = VersionInfo.class.getResourceAsStream("/META-INF/MANIFEST.MF")) {
Manifest manifest = new Manifest(is);
Attributes attributes = manifest.getMainAttributes();
version = attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}
catch (IOException e) {
throw new RuntimeException("Error loading META-INF/MANIFEST.MF file from classpath", e);
}
Ez fejlesztőeszközből indítva nem fog működni, csak ha JAR-ból futtatjuk. Ha web konténerben (pl. Tomcat) vagyunk,
és a META-INF
könyvtár nincs a classpath-on, akkor a ServletContext.getRealPath()
metódusát használjuk.
Ha mégis úgy döntünk, hogy szükségünk van build numberre is, mert SNAPSHOT verziót is azonosítani akarunk, akkor használhatjuk a Build Number Maven Plugin-t. Ez a bevezetőben említett összes forrásból képes kiolvasni a verzió paramétereket.
Amennyiben a következő konfigurációt használjuk, a verziókövető rendszert, pl. Gitet használ a
verzió információk kinyerésére. A buildNumber
property-be tárolja a commit hash-t, és
feltölti a timestamp
és buildScmBranch
property-ket is. Ehhez a háttérben egy Git parancsot ad ki.
Ehhez azonban kötelezően ki kell töltenünk az scm
tag-et a pom.xml
fájlban.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>buildNumber</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
Ha pl. környezeti változóból is szeretnénk értéket kinyerni, akkor a következő konfigurációval egészítsük ki:
<execution>
<id>jenkinsBuildNumber</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<buildNumberPropertyName>jenkinsBuildNumber</buildNumberPropertyName>
<format>{0}</format>
<items>
<item>${BUILD_NUMBER}</item>
</items>
</configuration>
</execution>
Ekkor a jenkinsBuildNumber
property értékét tölti fel a BUILD_NUMBER
környezeti változó
értékével.
Amennyiben ezeket az értékeket a MANIFEST.MF
-ben is szerepeltetni akarjuk, a következőt kell a pom-xml
-be írni
a maven-jar-plugin
konfigurációjánál:
<archive>
...
<manifestEntries>
<Implementation-Build>${buildNumber} ${jenkinsBuildNumber}</Implementation-Build>
</manifestEntries>
...
</archive>