Java SE 11のリリースまで3か月を切りました。みなさん、移行の準備は進んでいますでしょうか。
Java SE 11は、新しいリリースモデルになってはじめてのLTSになるバージョンです。なので、Java 9や10はすっ飛ばして、Java 11に移行することを考えている方も多いと思います。
しかし、Java 11への移行はいろいろ大変です。
今回は簡単なサンプルをベースにJava 11への移行を考えてみます。
Jersey + Grizzly
Jerseyは、JAX-RSのRIです。ということは、私よりもこれ読んでいる人の方が絶対に詳しいはずw
そのJerseyのUser GuideのGetting Startedに書いてあるサンプルを題材にしてみましょう。
このサンプルはMavenで勝手に作ってくれます。以下はGetting Startedからの引用です。
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \ -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \ -DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \ -DarchetypeVersion=2.27
さて、とりあえず、コンパイルしてみましょう。
C:\jersey-sample\simple-service>mvn compile [INFO] Scanning for projects... [INFO] [INFO] ---------------------< com.example:simple-service >--------------------- [INFO] Building simple-service 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ simple-service --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory C:\jersey-sample\simple-service\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ simple-service --- [INFO] Compiling 2 source files to C:\jersey-sample\simple-service\target\classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.721 s [INFO] Finished at: 2018-07-04T19:15:21+09:00 [INFO] ------------------------------------------------------------------------ C:\jersey-sample\simple-service>
依存しているライブラリがなければ、ダウンロードするログが出るはずですが、コンパイルは成功するはずです。
では、実行してみましょう。
C:\jersey-sample\simple-service>mvn exec:java [INFO] Scanning for projects... [INFO] [INFO] ---------------------< com.example:simple-service >--------------------- [INFO] Building simple-service 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) > validate @ simple-service >>> [INFO] [INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) < validate @ simple-service <<< [INFO] [INFO] [INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ simple-service --- 7月 04, 2018 7:29:51 午後 org.glassfish.jersey.internal.Errors logErrors 警告: The following warnings have been detected: WARNING: HK2 service reification failed for [org.glassfish.jersey.message.internal.DataSourceProvider] with an exception: MultiException stack 1 of 2 java.lang.NoClassDefFoundError: javax/activation/DataSource at java.base/java.lang.Class.getDeclaredConstructors0(Native Method) at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3114) <<以下、省略>>
NoClassDefFoundErrorで実行できませんでした。
このサンプルはJava 8までは普通に実行できます。でも、Java 11で実行できないのはJava EE (Jakarta EE)関連のAPIが削除されてしまったためです。
上の実行例でNoClassDefFoundErrorが出ているのは、javax.activation.DataSourceクラスがないためですが、このクラスはJavaBean Activation Framework (JAF) APIに含まれています。
他にも、JAXBのクラスもNoClassDefFoundErrorが出ています。
しかし、このサンプルのソースコードは、JAFもJAXBも使っていません。これらを使っているのは、JerseyやGrizzlyなのです。
だから、コンパイルは通るのに、実行はできないわけです。
JAXBは使っていないと安心されているかもしれませんが、多くのライブラリでJAXBやJAFを使っています。これが落とし穴になるわけですね。
解決法
では、Java 11で動作するようにしてみましょう。
今回はモジュールアプリケーションではないので、比較的簡単です。つまり、クラスパスに不足しているライブラリを追加するだけでOKです。
実際には、pom.xmlにJAXBとJAFへの依存を記述していきます。
変更したpom.xmlを以下に示します。赤字のところが変更した部分です。
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>simple-service</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple-service</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
<!-- uncomment this to get JSON support:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<inherited>true</inherited>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jersey.version>2.27</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
pluginのところの変更はバージョンを最新にしただけです。
重要なのは<dependencies>の部分。
依存しているライブラリとして
- jaxb-api
- jaxb-impl
- jaxb-core
- javax.activation-api
を追加しています。
これでビルドしなおしてから、実行してみましょう。
C:\jersey-sample\simple-service>mvn exec:java [INFO] Scanning for projects... [INFO] [INFO] ---------------------< com.example:simple-service >--------------------- [INFO] Building simple-service 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ simple-service --- 7月 04, 2018 20:24:38 午後 org.glassfish.grizzly.http.server.NetworkListener start 情報: Started listener bound to [localhost:8080] 7月 04, 2018 20:24:38 午後 org.glassfish.grizzly.http.server.HttpServer start 情報: [HttpServer] Started. Jersey app started with WADL available at http://localhost:8080/myapp/application.wadl Hit enter to stop it...
ここまで表示されたら、ブラウザでもcurlでもいいので、http://localhost:8080/myapp/myresourceにアクセスしてみてください。Got it!と表示されるはずです。
まとめ
- Java 11では、ほんとにJAXB、JAF、JAX-WSなどが削除されました
- 使っていないと思っていても、意外に使われているのがJAXBとJAF
- モジュールアプリケーションでなければ、クラスパスにJAXBとJAFのJarを追加するだけ
- Mavenであれば、pom.xmlの<dependencies>にJAXBとJAFを追加する
モジュールアプリケーションの場合はどうするのかについては、需要があれば書こうと思います。
0 件のコメント:
コメントを投稿