Reminiscence

感情の残骸

Kotlinからtwitter4j-streamのStatusListener等をaddListenerすると死ぬ問題について

Kotlinにてtwitter4jを使用し以下のようなコードを書くとIllegalAccessExceptionを吐いて死にます

val stream = TwitterStreamFactory().getInstance()
stream.addListener(UserStreamAdapter())

先に解決策だけ書いておくとJavaでラッパー作ると解決します

 public static void addStatusListener(TwitterStream stream, StatusListener listener){  
     stream.addListener(listener);  
 }  

なぜこういうことが起きるのかと言うと、Kotlinのコンパイラが吐き出すコードをデコンパイルしてみるとわかりますが、継承クラスであっても基底の引数として求められるクラスに一々キャストして渡しています。

先ほどの問題のKotlinのコードをデコンパイルしたものがこちらになります

TwitterStream stream = new TwitterStreamFactory().getInstance();
stream.addListener((StreamListener)new UserStreamAdapter());

ここで問題なんですが、キャストに使用されるStreamListenerはpackage privateになっており外側からはアクセスできません。参考
そのためJavaだと問題なく動くはずの上記のコードはStreamListenerにアクセスできずに落ちてしまいます、解決策では該当の部分だけをJavaで書いてやってキャストを避けることによって問題を回避しています。