こちらのエントリを見て面白そうだなぁと思い、断念されていた箇所の続きをやってみました。
Mavenのpom.xmlにあるプロジェクト情報をJSFで表示する
http://kikutaro777.hatenablog.com/entry/2014/01/31/232721
てっきり、pom.xmlの中の依存関係とかの話なのかなと思いましたが、pom.xmlに書かれている自身のアーティファクトのバージョンが欲しいということらしいです。
で、続きをやるのはこの部分。
相談にきた後輩はStackOverflowにあるMETA-INFフォルダにMANIFEST.MFを吐かせてImplementation-Versionを取得する流れで試してうまくいかなかったとのこと。
ちょっと思い当たるところがあるので、やってみようかと。
先のブログの例に習い、このようにpom.xmlを定義します。
バージョン情報。
<modelVersion>4.0.0</modelVersion> <groupId>org.littlewings</groupId> <artifactId>war-manifest</artifactId> <packaging>war</packaging> <version>0.1.1</version>
あえて、1.0.0ではなく0.1.1とかいう中途半端な値にしておきました。
プラグインも設定し、MANIFEST.MFにバージョン情報を書き出すようにしておきます。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> <archiveClasses>true</archiveClasses> </configuration> </plugin>
作成されたMANIFEST.MFは、このようになります。
META-INF/MANIFEST.MF
Manifest-Version: 1.0 Implementation-Title: war-manifest Implementation-Version: 0.1.1 Implementation-Vendor-Id: org.littlewings Built-By: xxxxx Build-Jdk: 1.7.0_51 Specification-Title: war-manifest Created-By: Apache Maven 3.1.1 Specification-Version: 0.1.1 Archiver-Version: Plexus Archiver
これを、WARファイルから読もうという試みです。
ClassLoaderから取得しようとすると、うまくいきません。今回は、ServletContextを使用しました。
src/main/java/org/littlewings/manifest/ShowManifestServlet.java
package org.littlewings.manifest; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.jar.Attributes; import java.util.jar.Manifest; import javax.servlet.ServletException; import javax.servlet.ServletContext; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/show") public class ShowManifestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter writer = res.getWriter(); // MANIFEST.MFを読み出すコード } }
まずは、普通に読んでみます。
StringBuilder builder = new StringBuilder(); try (InputStream is = getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"); InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(isr)) { int c; while ((c = reader.read()) != -1) { builder.append((char) c); } } writer.println(builder.toString());
ServletContext#getResourceAsStreamで、読み出しています。あとは、普通にReader系のクラスで中身を読みます。
続いて、境界を挟みまして。
writer.println("===========================");
続いては、java.util.jar.Manifestを使用する例。
try (InputStream is = getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF")) { Manifest manifest = new Manifest(is); Attributes attributes = manifest.getMainAttributes(); // Attributes#getValueで取得 writer.println("Implementation-Version => " + attributes.getValue("Implementation-Version")); writer.println("Specification-Version => " + attributes.getValue("Specification-Version")); // Attributes#getで取得その1 writer.println("Implementation-Version => " + attributes.get(Attributes.Name.IMPLEMENTATION_VERSION)); writer.println("Specification-Version => " + attributes.get(Attributes.Name.SPECIFICATION_VERSION)); // Attributes#getで取得その2 writer.println("Implementation-Version => " + attributes.get(new Attributes.Name("Implementation-Version"))); writer.println("Specification-Version => " + attributes.get(new Attributes.Name("Specification-Version"))); }
あとは、これをアプリケーションサーバにデプロイします。自分は、JBoss AS 7.1.1にデプロイしました。
今回、WARファイルの名前は「javaee6-web.war」としましたので、以下のURLにアクセスすると
$ curl http://localhost:8080/javaee6-web/show
このような結果になります。
Manifest-Version: 1.0 Implementation-Title: war-manifest Implementation-Version: 0.1.1 Implementation-Vendor-Id: org.littlewings Built-By: xxxxx Build-Jdk: 1.7.0_51 Specification-Title: war-manifest Created-By: Apache Maven 3.1.1 Specification-Version: 0.1.1 Archiver-Version: Plexus Archiver =========================== Implementation-Version => 0.1.1 Specification-Version => 0.1.1 Implementation-Version => 0.1.1 Specification-Version => 0.1.1 Implementation-Version => 0.1.1 Specification-Version => 0.1.1
最初が、普通にReaderで読んだもの、次がManifestクラスを使用したものですね。
こういうのを使うのはあまり機会がないので、たまにはよいでしょう。