Java

Java9以降でJAXB(SOAP)で作ったプログラムをTomcatで動かすためにやったこと

この記事に書いてあること

Java9以降では、SOAP通信を実現するための各種ライブラリであるAXBとかJAXWSとかが削除された影響でJAX系を使ったSOAP通信が出来なくなっているんですが、調べればすぐに依存関係を追加してやれば動くという記事が見つかります。
確かに、Mavenの依存関係を追加してやればJUnitを使った試験では簡単にSOAP通信が実施されました!

で、問題はここからで、そのアプリをTomcatに乗せたら動かないんですよ。わかる人が見たら別に当たり前の話なんですけど、私はそういうのは苦手なのでかなり苦戦しました。

その際の備忘メモを。ただし、これが正解かどうかは不明。とりあえず動くようにしたという話。Tomcatの設定が悪いのかな?

発生した問題

有名な話らしいのですが、Java8まではSOAP通信に使用するWSDLなんかを取り扱うJAXWSとかの関連ライブラリが標準で付属していました。

しかし、どういう訳かJava9以降ではそれらが標準付属ではなくなりました。
その影響としてJava8までで動いていたソースコードをJava9以降の環境で動かそうとするとJAXWS関連の処理でClassNotFoundとなります。
で、これの解決策を調べるとすぐに、依存ライブラリを入れれば動くという情報にたどり着きます。

しかし、それらの情報だけではEc;ipseに付属のTomcatでは動きませんでした。

今までmavenビルドでwarを作成していたのですが、関連するライブラリをwarに入れるのをやめてTomcatのlibフォルダに全部突っ込んだら動くようになりました。

この辺この辺を参考に以下のpomを作成しました。以下のpomにより、各種ライブラリがダウンロードされてEclipseでJUNITのコードを動かしたときはSOAPサーバにリクエストが飛んでいきました。

<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>
<dependency>
	<groupId>javax.xml.ws</groupId>
	<artifactId>jaxws-api</artifactId>
	<version>2.3.1</version>
</dependency>
<dependency>
	<groupId>com.sun.xml.ws</groupId>
	<artifactId>rt</artifactId>
	<version>2.3.1</version>
</dependency>

で、これをmavenビルドでwar化してEclipse付属のTomcatで動かしたところJAXWS関連のクラスが見つからずに実行時エラー。warを解体してみると関連ライブラリはちゃんと入っている。

解決した方法

上記全てのライブラリをprovidedにしたうえでwar内に含めるのをやめてTomcatのlibフォルダに直接配置したところ動きました。

<dependency>
	<groupId>javax.activation</groupId>
	<artifactId>javax.activation-api</artifactId>
	<version>1.2.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>javax.xml.bind</groupId>
	<artifactId>jaxb-api</artifactId>
	<version>2.4.0-b180830.0359</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.sun.xml.bind</groupId>
	<artifactId>jaxb-core</artifactId>
	<version>2.3.0.1</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.sun.xml.bind</groupId>
	<artifactId>jaxb-impl</artifactId>
	<version>2.4.0-b180830.0438</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>javax.xml.ws</groupId>
	<artifactId>jaxws-api</artifactId>
	<version>2.3.1</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.sun.xml.ws</groupId>
	<artifactId>rt</artifactId>
	<version>2.3.1</version>
	<scope>provided</scope>
</dependency>

Tomcatのlibに移動したjarファイルたちは以下。

  • jaxws-api-2.3.1.jar
  • javax.xml.soap-api-1.4.0.jar
  • javax.jws-api-1.1.jar
  • stax-ex-2.0.0.jar
  • streambuffer-1.5.3.jar
  • jaxb-impl-2.4.0-b180830.0438.jar
  • jaxb-api-2.4.0-b180830.0359.jar
  • rt-2.3.1.jar
  • jaxb-core-2.3.0.1.jar
  • stax2-api-4.1.jar
  • saaj-impl-1.5.0.jar
  • gmbal-api-only-3.1.0-b001.jar
  • management-api-3.0.0-b012.jar
  • policy-2.7.5.jar

これでいいのでしょうか。今後調べていきたいと思いますが、とりあえず動かすまでを優先ということで。

追加情報

providedなし、war内にライブラリを内包した場合のエラー

java.lang.ClassNotFoundException: javax.xml.ws.Service

providedなし、war内とTomcatのlibフォルダ両方に配置

javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/pleiades/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/SAMPLEAP/WEB-INF/lib/jaxb-api-2.4.0-b180830.0359.jar!/javax/xml/bind/JAXBContext.class to jar:file:/C:/pleiades/tomcat/9/lib/jaxb-api-2.4.0-b180830.0359.jar!/javax/xml/bind/JAXBContext.class.  Please make sure that you are specifying the proper ClassLoader.    

どっちを見たらいいかわからんというエラーですね。

###############お知らせ################
ブログランキングのITカテゴリに参加してみました。
この記事が役に立ったなどお力になれたら、 このバナーを押していただけると嬉しいです。

#####################################

-Java