java - How to make Kotlin stop casting argument to wrong class(Interface) -
i've been goofing around kotlin of recent, , it's been awesome!
i working twitter4j library tryout stuff twitter api. wrote code in kotlin
object demo { private val twitterstream = twitterstreamfactory().instance @jvmstatic fun main(args: array<string>) { val listener = object : statuslistener { override fun onstallwarning(warning: stallwarning?) { println("got stall warning:" + warning) } override fun onscrubgeo(userid: long, uptostatusid: long) { println("got scrub_geo event userid:$userid uptostatusid:$uptostatusid") } override fun onstatus(status: status) { println("@" + status.user.screenname + " - " + status.text) } override fun ondeletionnotice(statusdeletionnotice: statusdeletionnotice) { println("got status deletion notice id:" + statusdeletionnotice.statusid) } override fun ontracklimitationnotice(numberoflimitedstatuses: int) { println("got track limitation notice:" + numberoflimitedstatuses) } override fun onexception(ex: exception) { ex.printstacktrace() } } twitterstream.addlistener(listener) twitterstream.sample() } }
but each time ran it, got exception in thread "main" java.lang.illegalaccesserror: tried access class twitter4j.streamlistener class co.enoobong.eno.twitter.bot.demo @ co.enoobong.eno.twitter.bot.demo.main(demo.kt:63)
upon further investigation, tools->kotlin->show kotlin bytecode. decompiled java, discover being generated.
@jvmstatic public static final void main(@notnull string[] args) { intrinsics.checkparameterisnotnull(args, "args"); <undefinedtype> listener = new statuslistener() { public void onstallwarning(@nullable stallwarning warning) { string var2 = "got stall warning:" + warning; system.out.println(var2); } public void onscrubgeo(long userid, long uptostatusid) { string var5 = "got scrub_geo event userid:" + userid + " uptostatusid:" + uptostatusid; system.out.println(var5); } public void onstatus(@notnull status status) { intrinsics.checkparameterisnotnull(status, "status"); string var2 = "@" + status.getuser().getscreenname() + " - " + status.gettext(); system.out.println(var2); } public void ondeletionnotice(@notnull statusdeletionnotice statusdeletionnotice) { intrinsics.checkparameterisnotnull(statusdeletionnotice, "statusdeletionnotice"); string var2 = "got status deletion notice id:" + statusdeletionnotice.getstatusid(); system.out.println(var2); } public void ontracklimitationnotice(int numberoflimitedstatuses) { string var2 = "got track limitation notice:" + numberoflimitedstatuses; system.out.println(var2); } public void onexception(@notnull exception ex) { intrinsics.checkparameterisnotnull(ex, "ex"); ex.printstacktrace(); } }; twitterstream.addlistener((streamlistener)listener); twitterstream.sample();
}
kotlin trying cast listener streamlistener
private in library (statuslistener extends it) hence illegalaccesserror
any ideas how resolve please?
ps: here's working java version of code - https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/stream/printsamplestream.java
pps: i'm using kotlin 1.1.4, on intellij idea 2017.2.2
kotlin adds these casts ensure correct method called when dealing overloaded methods. problem occurs because public api addlistener
expects package-private interface streamlistener
. trying create such api causes warning because of problem , should fixed on twitter4j's side.
there no direct way fix in kotlin, can work around issue using java helper class , perhaps extension method:
class twitter4jfixer { public static void addlistener(twitterstream stream, statuslistener listener) { stream.addlistener(listener); } } fun twitterstream.addlistenerfixed(listener: statuslistener) { twitter4jfixer.addlistener(this, listener) }
Comments
Post a Comment