-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Dotty does not generate accessors for protected calls from inner classes, resulting in IllegalAccessError #2780
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
Thanks for providing a simple example demonstrating the problem! Here's a minmized test case showing the issue: package bla;
public class Base {
protected String foo = "";
}
class Foo extends bla.Base {
class Inner {
println(foo)
}
}
object Test {
def main(args: Array[String]): Unit = {
val f = new Foo
new f.Inner
}
} % javac try/Base.java -d .
% scalac try/i2780.scala
% scala Test
% dotc try/i2780.scala
% dotr Test
Exception in thread "main" java.lang.IllegalAccessError: tried to access field bla.Base.foo from class Foo$Inner
at Foo$Inner.<init>(i2780.scala:3)
at Test$.main(i2780.scala:10)
at Test.main(i2780.scala) This is easily explained by comparing the decompiled Foo.class: public class Foo
extends Base {
public /* synthetic */ String protected$foo(Foo x$1) {
return x$1.foo;
}
public Foo() {
}
public class Inner {
public final /* synthetic */ Foo $outer;
public /* synthetic */ Foo Foo$Inner$$$outer() {
return this.$outer;
}
public Inner(Foo $outer) {
if ($outer == null) {
throw null;
}
this.$outer = $outer;
Predef..MODULE$.println((Object)$outer.protected$foo($outer));
}
}
}
public class Foo
extends Base {
public Foo() {
}
public static class Inner {
private final Foo $outer;
public Inner(Foo $outer) {
if ($outer == null) {
throw new NullPointerException();
}
this.$outer = $outer;
Predef..MODULE$.println((Object)this.Foo$Inner$$$outer().foo);
}
private Foo $outer() {
return this.$outer;
}
public final Foo Foo$Inner$$$outer() {
return this.$outer();
}
}
} We failed to generate an accessor for the protected field |
There's at least one issue in |
Here's a WIP branch with the fix I suggested above if anyone wants to try to finish this, I don't think I'll have time to do it myself in the near future: https://github.com/dotty-staging/dotty/commits/fix-i2780 |
@bbarker This should be fixed in the latest nightly, you can try it out by setting |
I hazard a guess this is an issue with handling multiple classloaders. This small project demonstrates the issue.
The problem seems to occur when an anonymous or inner class is created that accesses a protected or private member in the outer class. However, I've only been able to reproduce the error when my outer class extends a class implemented in some (java) library - this is the
HelloInput.scala
example in the repo (and the protected variable in question isspeed
). The example inMain.scala
uses the same approach with a minimal example implemented completely in the project, and seems to work fine.Stack trace in dotty:
To reproduce:
sbt runHelloInput
To compare to scalac, just change the
scalaVersion :=
inbuild.sbt
.The text was updated successfully, but these errors were encountered: