Zistenie verzie JARu z manifestu za behu

V mnohých projektoch by sme chceli mať možnosť zisťovať verzie aktuálneho modulu, a to za behu. Napríklad sa hodí vedieť, že práve bežíme na projekte verzie 0.0.1-SNAPSHOT.

Jedna z veľmi ízy možností využíva polozabudnuté API zo štandardnej Javy, a to najmä triedu java.lang.Package, v kombinácii s manifestami v JAR archívoch.

Zistenie verzie knižnice

Týmto spôsobom vieme veľmi jednoducho zistiť verziu napr. logovacej knižnice Commons Logging-u. Zaveďme ho do projektu: buď tak, že ho zavedieme do CLASSPATH ako knižnicu alebo využijeme správcu závislostí, napríklad Maven::

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>sk.upjs.ics.novotnyr</groupId>
    <artifactId>manifest-version-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>
    </dependencies>
</project>

Potom si môžeme vytvoriť ukážkovú triedu:

package sk.upjs.ics.novotnyr.mvd;

import org.apache.commons.logging.Log;

public class CommonsLoggingVersion {
    public static void main(String[] args) {
        String implementationVersion = Log.class.getPackage().getImplementationVersion();
        System.out.println(implementationVersion);
    }
}

Ak ju spustíme, výsledok v konzole bude:

1.1.3

Informácia sa nevycucala z prsta, ale z manifestu, teda zo súboru MANIFEST.MF, ktorý sa nachádza v adresári META-INF v archíve commons-logging-1.1.3.jar.

Presnejšie, zoberieme ľubovoľnú triedu z JAR archívu, o ktorom chceme získať verzionovacie informácie (trieda org.apache.commons.logging.Log je dobrý kandidát), získame inštanciu objektu Class príslušnej triedy a z nej získame objekt pre balíček, teda Package.

Pomocou neho sa automaticky naparsuje manifest príslušného archívu. V našom príklade je manifest značne komplikovaný, ale stačí si všímať pasáže:

Implementation-Title: Commons Logging
Implementation-Vendor: The Apache Software Foundation
Implementation-Vendor-Id: org.apache
Implementation-Version: 1.1.3

Trieda java.lang.Package dokáže spracovať hlavičku Implementation-Version, načítať ju a priamo k nej pristúpiť. Nemusíme teda pracne načítavať manifesty, hľadať ich umiestnenia a riešiť ich parsovanie: to všetko sa spraví za nás.

Pozor však! Toto funguje len pre manifesty v JAR archívoch!

Vlastný projekt s verziou [pomocou Mavenu]

Niečo podobné vieme dosiahnuť za pomoci Mavenu. Budeme potrebovať:

  • vygenerovať manifest
  • nakonfigurovať JAR plug-in v pom.xml
  • vytvoriť triedu, ktorá vypíše verziu za behu

Generovanie manifestu

Generovanie manifestu zaistí plug-in pre tvorbu JAR-ov. Tento krok je teda jednoduchý.

Konfigurácia JAR plug-inu v pom.xml

Do pom.xml stačí zaviesť nový plug-in:

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

Stačí dodať klauzulu addDefaultImplementationEntries, ktorou zapneme generovanie hlavičiek do automaticky vytváraného manifestu.

Ak zostavíme projekt cez mvn package, výsledkom bude JAR archív s automaticky generovaným manifestom:

Manifest-Version: 1.0
Implementation-Title: manifest-version-demo
Implementation-Version: 0.0.1-SNAPSHOT
Implementation-Vendor-Id: sk.upjs.ics.novotnyr
Built-By: rn
Build-Jdk: 1.7.0_25
Created-By: Apache Maven 3.0.5
Archiver-Version: Plexus Archiver

Vytvorenie triedy, ktorá vypíše verziu za behu

Toto sme už videli v predošlej sekcii:

package sk.upjs.ics.novotnyr.mvd;

public class Version {
    public static void main(String[] args) {
        Package aPackage = Version.class.getPackage();
        String implementationVersion = aPackage.getImplementationVersion();
        System.out.println(implementationVersion);
    }
}

Spustenie projektu

Ak chceme spustiť projekt, musíme ho zostaviť ako JAR. V samotnom IDE fungovať nebude — výsledkom na konzole bude null — pretože parsovanie manifestu funguje výhradne v JAR archívoch. (Inými slovami, ak spustíte Version z Eclipsu, uvidíte null.)

To však neprekáža:

  • zostavíme projekt cez mvn package. Výsledkom bude `manifest-version-demo-0.0.1-SNAPSHOT.jar, ktorý…
  • … spustíme cez

    java -cp target\manifest-version-demo-0.0.1-SNAPSHOT.jar sk.upjs.ics.novotnyr.mvd.Version
    

    Výsledkom tak bude:

    0.0.1-SNAPSHOT 
    

3 thoughts on “Zistenie verzie JARu z manifestu za behu

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *