Aladdin - Scala Bugtracking
[#268] project: compiler priority: medium category: bug
submitter assigned to status date submitted
Vincent Michel fixed 2004-01-06 19:10:43.0
subject IllegalAccessError
code
object bug with Executable {
  private var x = 42; // "private" and "var" necessary for the bug
  def id[a](def y: a) = y; // "polymorphism", "def" and "y" necessary for the bug
  id(x);
}
what happened

Silent run with java -cp scala.jar:. bug.

But with java -Xbootclasspath/a:scala.jar:. bug:

Exception in thread "main" java.lang.IllegalAccessError: tried to access method bug$.x()I from class bug$$anon$0\

what expected The second way of calling the program is in fact the one used when executing the command scala. The problem can occur quite often, in particular each time a private variable is used inside a synchronized statement.
[back to overview]
Changes of this bug report
Philippe  edited on  2004-01-06 19:50:07.0

Here is a simplified example:

object Test { private def x: Int = 0; class Inner { x } new Inner(); final def main(args: Array[String]): Unit = (); }

The problem is that we neither generate an interface for class Test nor make all its private method non-private, so we end up calling the private method Test.x from inner class Inner. However, it's very strange that this works if the classes are found in the classpath.

Erik  edited on  2004-01-08 13:51:34.0
I changed priority to high since this is a very annoying bug. Arguments to functions are automatically private so you don't even have to have explicit private fields in order to be bitten byt this. In the following test class in the top level package the first println works but not the second. ---
object t with Executable {
  def f(g:int=>int) = (s:int) => (1::Nil).map((x:int)=>g(s));

  Console.println(f((x:int) => x)(42));
  Console.println(scala.testing.QuickCheck.f((x:int) => x)(42));
}
---
package scala.testing;
object QuickCheck {

  def f(g:int=>int) = (s:int) => (1::Nil).map((x:int)=>g(s));

}
Test:
scala -classpath ./classes t
List(42)
Exception in thread "main" java.lang.IllegalAccessError: tried to access method scala.testing.QuickCheck$$anon$12.g$1()Lscala/Function1; from class scala.testing.QuickCheck$$anon$12$$anon$34
        at scala.testing.QuickCheck$$anon$12$$anon$34.apply(sources/scala/testing/QuickCheck.scala:276)
        at scala.testing.QuickCheck$$anon$12$$anon$34.apply(sources/scala/testing/QuickCheck.scala:276)
        at scala.List$class.map(sources/scala/List.scala:351)
        at scala.testing.QuickCheck$$anon$12.apply(sources/scala/testing/QuickCheck.scala:276)
        at scala.testing.QuickCheck$$anon$12.apply(sources/scala/testing/QuickCheck.scala:276)
        at t$.(test.scala:7)
        at t$.(test.scala)
        at t.main(test.scala)
Michel  edited on  2004-01-08 15:26:05.0
I fixed the bug in a relatively crude fashion, by simply renaming and making public all members. I don't know of another solution, though.
Michel  edited on  2004-01-08 15:26:40.0
(In my last comment, I meant renaming all private members, of course)