google-oauth-client-jettyとjetty-serverのバージョンコンフリクトを解決する
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がライブラリを直せば最新版にアップデート出来るので対処療法としてこれで妥協することにします.