結論からいうと
「Scala2.10でGoogle App Engine内からhttpリクエスト投げるときは、scalaj-http0.3.6を使うとうまくいく」
versionがそれより古くても新しくてもだめ。
理由は
- scalaj-http0.3.2以前はScala2.10対応版なし
- 0.3.3から0.3.5にかけては、Scala2.10だと超致命的なバグが有り全く使いものにならない
- 0.3.7以降は、java.net.Proxyのクラス参照してて、セキュリティ上(?)エラーになる
- 最新版の0.3.14では、リフレクション使ってるので更にだめ
java.lang.NoClassDefFoundError: java.net.Proxy is a restricted class. Please see the Google App Engine developer's guide for more details. at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51) at scalaj.http.Http$Request$.apply$default$7(Http.scala:101) at scalaj.http.Http$Request$.apply(Http.scala:96) at scalaj.http.Http$.get(Http.scala:281) at scalaj.http.Http$.apply(Http.scala:90)
でさらにいうとdispatch-classic 0.8.10 使ってみたら以下のようなエラーになった。
com.google.apphosting.api.ApiProxy$FeatureNotEnabledException: The Socket API will be enabled for this application once billing has been enabled in the admin console. java.lang.Thread.getStackTrace(Thread.java:1568) com.google.apphosting.runtime.ApiProxyImpl.doSyncCall(ApiProxyImpl.java:253) com.google.apphosting.runtime.ApiProxyImpl.access$000(ApiProxyImpl.java:64) com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:196) com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:193) java.security.AccessController.doPrivileged(Native Method) com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:193) com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:64) com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:107) com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:56) com.google.appengine.api.socket.SocketApiHelper.apiProxyMakeSyncCall(SocketApiHelper.java:90) com.google.appengine.api.socket.SocketApiHelper.makeSyncCall(SocketApiHelper.java:58) com.google.appengine.api.socket.NameServiceImpl.lookupAllHostAddr(NameServiceImpl.java:61) com.google.apphosting.util.ResolverManager$AppEngineNameservice.lookupAllHostAddr(ResolverManager.java:42) java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1388) java.net.InetAddress.getAllByName0(InetAddress.java:1341) java.net.InetAddress.getAllByName(InetAddress.java:1255) java.net.InetAddress.getAllByName(InetAddress.java:1186) org.apache.http.impl.conn.DefaultClientConnectionOperator.resolveHostname(DefaultClientConnectionOperator.java:242) org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:130) org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121) org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:575) org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:776) dispatch.classic.BlockingHttp$class.dispatch$classic$BlockingHttp$$execute(Http.scala:45) dispatch.classic.BlockingHttp$$anonfun$execute$1$$anonfun$apply$3.apply(Http.scala:58) dispatch.classic.BlockingHttp$$anonfun$execute$1$$anonfun$apply$3.apply(Http.scala:58) scala.Option.getOrElse(Option.scala:120) dispatch.classic.BlockingHttp$$anonfun$execute$1.apply(Http.scala:58) dispatch.classic.Http.pack(Http.scala:25) dispatch.classic.BlockingHttp$class.execute(Http.scala:53) dispatch.classic.Http.execute(Http.scala:21) dispatch.classic.HttpExecutor$class.x(executor.scala:36) dispatch.classic.Http.x(Http.scala:21) dispatch.classic.HttpExecutor$class.when(executor.scala:50) dispatch.classic.Http.when(Http.scala:21) dispatch.classic.HttpExecutor$class.apply(executor.scala:60) dispatch.classic.Http.apply(Http.scala:21)
これも結局dispatchが内部で依存してるApacheのhttp clientが、GAE上で使用禁止のsocketのAPIを使っていてだめらしい。(金払えとかいうエラーメッセージぇ・・・)
使い方変えれば回避できるのかもしれない?が、面倒なので調べてないdispatchはそのためのGAEのモジュールありますね https://github.com/dispatch/dispatch/blob/0.8.9/project/build.scala#L80-L86
で、流石にscala.io.Sourceは使いたくないし、そもそもの目的は、GAE上からgithubのAPI呼び出したかったのだが
など、色々とハマった。疲れた