-
Notifications
You must be signed in to change notification settings - Fork 21
IllegalAccessError with mixed Scala/Java due to trait encoding #2296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Imported From: https://issues.scala-lang.org/browse/SI-2296?orig=1 |
@paulp said: def bar() {
super.foo()
} and scala s.Test says "J.foo()". The bytecode looks like this, as a result of the mangling in SuperAccessors. Perhaps this is as simple as identifying this situation during that phase and treating it like a super invocation? public static void bar(s.S);
Code:
0: aload_0
1: invokeinterface SI-16, 1; //InterfaceMethod s/S.s$$S$$$$super$$foo:()V
6: return |
@paulp said: |
Antony Stubbs (astubbs) said: Weird thing is. Idea runs the code just fine :? as retronym points out: |
@dragos said: |
@paulp said: |
@hubertp said: |
Matthew Pocock (drdozer) said: trait SessionStore {
self : GenericAutowireComposer =>
// also tried this.session and session
def getUser: Option[User] = Option(self.session.getAttribute("user").asInstanceOf[User]
}
class FooCtrl extends GenericAutowireComposer with SessionStore { ... } At run-time, I get an IllegalArgumentException: java.lang.IllegalAccessError: tried to access field org.zkoss.zk.ui.util.GenericAutowireComposer.session from class FooCtrl$$class
at FooCtrl$$class.setUser I can see that 'fixing' this so that it actually works could be a royal pain. However, generating bytecode that attempts to access protected fields in other classes can't be a Good Thing. Shouldn't this kind of access violation be caught by something in the compiler guts? |
@paulp said: |
@paulp said: |
@hubertp said: |
@paulp said: |
@hubertp said: |
@hubertp said: package bug;
class A {
public void addAction(bug.action.Action a) {
...
}
} bug/Display.java package bug;
class Display {
protected A sth;
} bug/action/Action.java package bug.action;
public abstract class Action {
protected A sth;
public abstract void run();
} and scala code package test;
abstract class MyDisplay extends bug.Display {
def init() {
sth.addAction(ScalaAction)
}
object ScalaAction extends action.Action {
def run() {
sth. // call some method on A, crashes on runtime with illegal access
}
}
} The surprising thing is that, if I make ScalaAction a class (and change addAction(...) to addAction(new ScalaAction())) this thing works again. |
@hubertp said: package bug;
import bug.action.Action;
import java.util.List;
import java.util.LinkedList;
public class Global {
public int items() {
return 0;
}
public int items(int i) {
return i + ls.size();
}
private List<Action> ls = new LinkedList<Action>();
public void putAction(Action a) {
a.setGlobal(this);
ls.add(a);
}
public void runActions() {
for (Action action: ls) {
System.out.println("RUNNING ACTION");
action.run(0);
}
}
} bug/Display.java package bug;
public class Display {
protected Global m_glob;
public void start() {
m_glob.runActions();
}
} bug/action/Action.java package bug.action;
import bug.Global;
public abstract class Action {
protected Global m_glob;
public Action(Global glob0) {
m_glob = glob0;
}
public Action() {
this(null);
}
public abstract void run(int v);
public void setGlobal(Global g) {
m_glob = g;
}
} test/ScalaActivity.scala package test
import bug.Display
import bug.action.Action
abstract class Outer extends Display {
def init() {
m_glob.putAction(ScalaActivity)
}
object ScalaActivity extends Action {
def run(v: Int) {
val testSet = List(1,2,3)
testSet.map(p => m_glob.items(p)) // crash with illegal access
}
}
} test/Test.scala package test
import bug.Global
object Test {
def main(args: Array[String]) {
val m = new Main()
m.init()
m.start()
}
}
class Main extends Outer {
m_glob = new Global()
} Making ScalaAction a class instead of an object fixed the problem. Closure in run method is necessary to trigger the illegal access error. |
@paulp said: |
@dotta said: This is of course no high priority (it might as well never be backported). |
@hubertp said: |
@dotta said (edited on Jun 19, 2012 5:03:48 PM UTC): In short, I tried to merge your pull-request (scala-ide/scala-ide#80) but had to rollback right after because of http://scala-ide-portfolio.assembla.com/spaces/scala-ide/tickets/1001083. If you want to investigate, I'd be delighted ;) |
This issue is present on both trunk and 2.7.x.
j/J.java:
s/S.scala:
These compile without error (either compiling the Java first then the Scala; or compiling both the Scala and Java with scalac first, then the Java with javac). On running the following stacktrace is generated,
Viewing the bytecode for s.S$$class shows why this is the case:
J.foo is invoked from s.S$$class which does not extend j.J despite trait s.S extending j.J.
It would be great if this could be fixed, but presumably that would involve a significant change to the encoding of traits, so I'd settle for a compile time error for this case.
The text was updated successfully, but these errors were encountered: