• 作成:

google-oauth-client-jettyとjetty-serverのバージョンコンフリクトを解決する

google-oauth-java-clientの最新版にはバグがあります

Jetty exception NoSuchMethodError: org.eclipse.jetty.server.Connector.setHost · Issue #397 · googleapis/google-oauth-java-client

というバグで,1.30.4から発生しています.

これ回避方法探しましたが全く分かりませんでした…

ではダウングレードすれば良いのではないかと言うとそう簡単な話でもない

1.30.4から発生ならば1.30.3に戻せば良いのでは無いかと思われるでしょう.もちろん私もそう思って書き換えました.

すると

java.lang.NoSuchMethodError: 'boolean javax.servlet.http.HttpServletRequest.isAsyncSupported()'

というエラーが発生します.

java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.isAsyncStarted() while using Mockito with Junit - Stack OverflowによるとServletのバージョンが合わないことによるバグらしいですね.

何故これをコンパイルエラーにせずに実行時に動的ローディングするんでしょう.とても苦しみます.

でもマネージドで依存している以上jetty-serverはちゃんとServletを依存関係に指定しているはずですよね…

よくわからないので全部のjarを見ましょう.

gradle dependencies

はsbtなので使えないので

sbt 'show compile:dependencyClasspath;'|sort|less

という手段を使わせて貰いました.

なるほど確かに依存関係に

[info] * Attributed(/home/ncaq/.cache/coursier/v1/https/repo1.maven.org/maven2/org/mortbay/jetty/servlet-api/2.5-20081211/servlet-api-2.5-20081211.jar)

があってとても怪しいですね.

jrudolph/sbt-dependency-graph: sbt plugin to create a dependency graph for your projectが使えればよかったのですがsbtの最新版に対応していないので,勘と2分探索でgoogle-oauth-client-jettyのバージョン1.30.3以前がorg.mortbay.jetty » jettyという古いjettyに依存していることがわかりました.

この古いjettyはServletのjarをマネージドではなくバンドルする形で依存しているらしいですね.Maven Repository: org.mortbay.jetty » servlet-api » 3.0.20100224がそれを担っている…?なんで公式のパッケージに依存しないんでしょうね?

まあともかくバージョン1.30.3以前がこの問題を抱えているならば1.30.4以後にアップデートすれば解決ですね!

Jetty exception NoSuchMethodError: org.eclipse.jetty.server.Connector.setHost · Issue #397 · googleapis/google-oauth-java-clientがあるから上げられないじゃん…

jetty-serverをorg.mortbay.jetty版にいっそのこと変更してみたら合わさって良いのではないかと試してみましたが,流石に古すぎてアプリケーションコードがぶっ壊れました.

解決策

どうやらsbtはexcludeを使うことで依存関係の依存関係を無理やりカットすることが出来るようです.それにて強引に解決がなされました.

"com.google.oauth-client"   % "google-oauth-client-jetty"  % "1.30.3" exclude ("org.mortbay.jetty", "servlet-api"),

これで動いたのでとりあえずは良いということにします.強引に依存関係を取り除いたので本当にこれで良いのかすごい不安ですが,Googleがライブラリを直せば最新版にアップデート出来るので対処療法としてこれで妥協することにします.