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 件のコメント:
コメントを投稿