Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-2296

IllegalAccessError with mixed Scala/Java due to trait encoding

    Details

      Description

      This issue is present on both trunk and 2.7.x.

      j/J.java:

      package j;
       
      public class J {
        protected void foo() {
          System.out.println("J.foo()");
        }
      }
      

      s/S.scala:

      package s
       
      import j.J
       
      trait S extends J {
        def bar() {
          foo()
        }
      }
       
      class SC extends J with S
       
      object Test {
        def main(args : Array[String]) {
          (new SC).bar()
        }
      }
      

      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,

      java.lang.IllegalAccessError: tried to access method j.J.foo()V from class s.S$$class
      	at s.S$$class.bar(S.scala:7)
      	at s.SC.bar(S.scala:11)
      	at s.Test$$.main(S.scala:15)
      	at s.Test.main(S.scala)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at scala.util.ScalaClassLoader$$$$anonfun$$run$$1.apply(ClassLoader.scala:54)
      	at scala.util.ScalaClassLoader$$class.asContext(ClassLoader.scala:21)
      	at scala.util.URLClassLoader.asContext(ClassLoader.scala:58)
      	at scala.util.ScalaClassLoader$$class.run(ClassLoader.scala:54)
      	at scala.util.URLClassLoader.run(ClassLoader.scala:58)
      	at scala.tools.nsc.ObjectRunner$$.run(ObjectRunner.scala:33)
      	at scala.tools.nsc.MainGenericRunner$$.main(MainGenericRunner.scala:138)
      	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
      

      Viewing the bytecode for s.S$$class shows why this is the case:

      public abstract class s.S$$class extends java.lang.Object{
      public static void $$init$$(s.S);
        Code:
         0:	return
       
      public static void bar(s.S);
        Code:
         0:	aload_0
         1:	checkcast	SI-12; //class j/J
         4:	invokevirtual	SI-16; //Method j/J.foo:()V
         7:	return
      }
      

      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.

        Attachments

          Activity

            People

            • Assignee:
              extempore Paul Phillips
              Reporter:
              milessabin Miles Sabin
              TracCC:
              Antony Stubbs, Ben Lings, Erik Engbrecht, Ismael Juma, Johannes Rudolph, Matthew Pocock, Paul Phillips, spiros
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: