[#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 |
|
|||
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] |
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$. |
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) |