はじまり
ありのまま。今起こったことを話すぜ。俺は最新のSwagger Editorでコードを作ったんだ。自動生成されたコードをmvn package
するとエラーがはかれてしまうんだ。何を言っているかわからないだろうが、俺も何が起きているのが分からなかった。催眠術や、超スピードなんてチャチなものじゃ断じてない。何かすごいものの片鱗を俺はあじわったぜ。。。
と、いつものようにポルナレフですが。けっこうはまる人ははまるので、残しておきます。
ぼくと同じようにはまった人が、無駄に時間を費やさないでくれたらうれしいな。
具体的には?
実行環境
No | 環境項目 | 備考 |
---|---|---|
1 | Java | openjdk 17 2021-09-14 |
2 | maven | Apache Maven 3.6.3 |
3 | swagger-editor | https://editor.swagger.io/ |
やったこと
- Swaggerファイルを作成@swagger-editor
- SpringBootコードを生成
- mvn package
つまり、ゲームスタート!⇒クリボーに食われて即死!! です。初見殺しなので、心の弱い人はここで諦めます。
ありのままを話すぜ
JEP 320襲撃!!
つまりこういう状態です。
spring-server> mvn clean package
[INFO] Scanning for projects...
…
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ swagger-spring ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 14 source files to spring-server-generated \spring-server\target\classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] resoruces/program/spring-server-generated /spring-server/src/main/java/io/swagger/api/ApiResponseMessage.java:[3,33] パッケージjavax.xml.bind.annotationは存在しません
[ERROR] resoruces/program/spring-server-generated /spring-server/src/main/java/io/swagger/api/ApiResponseMessage.java:[7,27] パッケージjavax.xml.bind.annotationは存在しません
[ERROR] resoruces/program/spring-server-generated /spring-server/src/main/java/io/swagger/api/ApiResponseMessage.java:[46,6] シンボルを見つけられません
シンボル: クラス XmlTransient
場所: クラス io.swagger.api.ApiResponseMessage
[INFO] 3 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
あれ。。たしか5年前に同じようなことやってできてたはず。。。 あれは確か Java 8... ピコーン。java 9から非推奨になってた奴が刈り取られたんだな。
ありますね。JEP-320。 つまり、今使っているJDK17は初期状態でこのパッケージ使えないってことですが。
- 奥様、奥様。慌てることはありません。
-
そうよね!!最初から入っていないのなら、たしてしまえばいいのよね
(このネタ知ってる人いるのかな。)
ないのなら足してしまえばいいだけなのです。ここがJavaのいいところ。廃止決定⇒則排除しないだけではなくわりと昔のプログラムに対する回避策も用意されていることが素晴らしい。
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.4.0-b180830.0438</version>
</dependency>
さて、実行してみましょう。
\spring-server> mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< io.swagger:swagger-spring >----------------------
[INFO] Building swagger-spring 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ swagger-spring ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ swagger-spring ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 14 source files to spring-server\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.479 s
[INFO] Finished at: 2021-11-21T09:39:05+09:00
[INFO] ------------------------------------------------------------------------
難なくおわりました。
Package するぞ‼!
コンパイルが通るので、このままパッケージまで行けると思いますよね。なんせ自動生成ですから。でもね。そんな簡単なもんじゃないんですよね。。
はい。できましたー
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-jar-plugin:2.6:jar (default-jar) on project swagger-spring: Execution default-jar of goal org.apache.maven.plugins:maven-jar-plugin:2.6:jar failed: An API incompatibility was encountered while executing org.apache.maven.plugins:maven-jar-plugin:2.6:jar: java.lang.ExceptionInInitializerError: null
どうやら、デフォルト状態で使われるのmaven-jar-pluginがダメなんですね。なので、きちんと指定してあげましょう。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<jdkToolchain>
<version>9</version>
</jdkToolchain>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
はい。うまくいきました。
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.641 s
[INFO] Finished at: 2021-11-21T09:48:18+09:00
[INFO] ------------------------------------------------------------------------
まとめると
Javaは素晴らしい言語です。言語仕様で必要とされる機能を網羅し、設計、製造、運用に至るまでがっちりと設計されています。後方互換も常に配慮してくれていますが、それでもメンテナンスは必要です。そしてJavaを取り巻く多くのエコシステムはJava8 ベースで存在します。残念ながら、そのうちのいくつかは、そのまま取り残されてしまうでしょう。それでも、昔の資産を使うための方法を知っていれば、何とかなります。最悪ソースを書き直して自分様にブランチさせればいいのですが、そうではない道もあるので、一歩一歩着実に進んで行きましょう。
まだ、実行確認してないので、そこではまったらその顛末は別にレポートします。
11/22 追記
最新版のcodegenでも同様のエラーが出ます。
参考文書
https://github.com/acroquest/javabook-support/issues/49
https://stackoverflow.com/questions/46353477/jdk9-and-maven-jar-plugin