Scala Programming Language
  1. Scala Programming Language
  2. SI-5165

Scala compiler reports class file is broken when the class is annotated with a Java annotation having multiple enum values

    Details

      Description

      I discovered this issues while annotating some of scala traits with Jackson type annotations (http://jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/annotate/JsonTypeInfo.html). The issues seems to be that the JsonTypeInfo annotation has two properties that reference inner non-static enumerations. The scala compiler appears to generate valid class files, but cannot load these class to compile other dependent source files.

      I've managed to reproduce the issue outside of Jackson:

      $ javac -version
      javac 1.6.0_26
      $ scalac -version
      Scala compiler version 2.9.2.r25928-b20111102031955 -- Copyright 2002-2011, LAMP/EPFL
      
      $ javac TestAnnotation.java 
      $ scalac TestTrait.scala 
      $ scalac TestObject.scala 
      error: error while loading TestTrait, class file './TestTrait.class' is broken
      (Scala class file does not contain Scala annotation)
      TestObject.scala:2: error: illegal inheritance;
       self-type TestObject.type does not conform to TestTrait's selftype TestTrait
      object TestObject extends TestTrait
                                ^
      TestObject.scala:2: error: illegal inheritance; superclass TestTrait
       is not a subclass of the superclass Object
       of the mixin trait ScalaObject
      object TestObject extends TestTrait
                        ^
      three errors found
      

      The source (also attached):

      TestAnnotation.java
      import java.lang.annotation.*;
      
      @Retention(RetentionPolicy.RUNTIME)
      public @interface TestAnnotation {
        public enum TestEnumOne { A, B }
        public enum TestEnumTwo { C, D }
      
        public TestEnumOne one();
        public TestEnumTwo two();
        public String strVal();
      }
      
      TestTrait.scala
      @TestAnnotation(one=TestAnnotation.TestEnumOne.A, two=TestAnnotation.TestEnumTwo.C, strVal="something")
      trait TestTrait
      
      TestObject.scala
      object TestObject extends TestTrait
      

      Other Observations:

      • Making TestEnumOne and TestEnumTwo static still produces the error
      • Compiling both TestTrait.scala and TestObject.scala together does not produce the error
      • Having only one enum filed in TestAnnotation (i.e. commenting out "public TestEnumTwo two()" in TestAnnotation.java) does not produce the error
      1. test.tbz
        0.4 kB
        Bryan Gahagan

        Issue Links

          Activity

          Hide
          Paul Phillips added a comment -

          Noting for the record that I checked in a test case for this thinking it was fixed because eugene's error as given above no longer occurs, it compiles if all source; but the classfile parsing bug remains so this isn't fixed. I'm looking at that now.

          Show
          Paul Phillips added a comment - Noting for the record that I checked in a test case for this thinking it was fixed because eugene's error as given above no longer occurs, it compiles if all source; but the classfile parsing bug remains so this isn't fixed. I'm looking at that now.
          Hide
          Simon Ochsenreither added a comment -

          The problem with the class-parser is probably related to SI-5699.

          Show
          Simon Ochsenreither added a comment - The problem with the class-parser is probably related to SI-5699 .
          Hide
          Raman Gupta added a comment -

          FYI - for anyone running into this issue who is using Jackson annotations – one workaround is to add the annotation to the scala class using a java mixin class. See here: http://wiki.fasterxml.com/JacksonMixInAnnotations.

          Show
          Raman Gupta added a comment - FYI - for anyone running into this issue who is using Jackson annotations – one workaround is to add the annotation to the scala class using a java mixin class. See here: http://wiki.fasterxml.com/JacksonMixInAnnotations .
          Hide
          Adriaan Moors added a comment -

          Compiles with scalac 2.11.0-M8

          Show
          Adriaan Moors added a comment - Compiles with scalac 2.11.0-M8
          Hide
          Jason Zaugg added a comment -

          Paul's test case from source:

          commit 3511e5960d510eafcb67c388ec0b5b60aafdd8f3
          Author: Paul Phillips <paulp@improving.org>
          Date:   Fri May 11 11:06:55 2012 -0700
          
              Test case closes SI-5165.
          
              Also fixed by annotation/enum commit.
          
          commit 807567230852bcadb98a91322bd348aae764801f
          Author: Paul Phillips <paulp@improving.org>
          Date:   Fri May 11 10:25:34 2012 -0700
          
              Recognize java enums as constants from source.
          
              Fixed up one of the mismatches between how java source is modeled
              and how java bytecode is modeled.  We should get the rest of them
              too.  Closes SI-2764.
          

          Looks like this started working in:

          commit dc6a49337f072686516c14f50b847c38cbc6c225
          Author: Miguel Garcia <miguelalfredo.garcia@epfl.ch
          Date:   Fri Jul 6 17:06:57 2012 +0200
          
              GenASM becomes default backend, 1.5 classfiles
          
          % (export V=dc6a493; rm *.class; javac -d . test/files/pos/t5165b/TestAnnotation_1.java && scalac-hash $V test/files/pos/t5165b/TestTrait_2.scala && scalac-hash $V test/files/pos/t5165b/TestObject_3.scala)
          
          % (export V=dc6a493~1; rm *.class; javac -d . test/files/pos/t5165b/TestAnnotation_1.java && scalac-hash $V test/files/pos/t5165b/TestTrait_2.scala && scalac-hash $V test/files/pos/t5165b/TestObject_3.scala 2>&1 | tail -n 8)
           self-type TestObject.type does not conform to TestTrait's selftype TestTrait
          object TestObject extends TestTrait
                                    ^
          test/files/pos/t5165b/TestObject_3.scala:2: error: TestTrait does not have a constructor
          object TestObject extends TestTrait
                            ^
          two warnings found
          5 errors found
          
          % for i in 10.0 10.2 10.3 11.0-M8; do (export V=v2.$i; rm *.class; javac -d . test/files/pos/t5165b/TestAnnotation_1.java && scalac-hash $V test/files/pos/t5165b/TestTrait_2.scala && scalac-hash $V test/files/pos/t5165b/TestObject_3.scala); done
          [warn] v2.11.0-M8 failed, using closest available
          [warn] v2.11.0-M8 failed, using closest available
          

          I've submitted a test case to keep it fixed. This test case used the same compilation order as reported above: https://github.com/scala/scala/pull/3548

          Show
          Jason Zaugg added a comment - Paul's test case from source: commit 3511e5960d510eafcb67c388ec0b5b60aafdd8f3 Author: Paul Phillips <paulp@improving.org> Date: Fri May 11 11:06:55 2012 -0700 Test case closes SI-5165. Also fixed by annotation/enum commit. commit 807567230852bcadb98a91322bd348aae764801f Author: Paul Phillips <paulp@improving.org> Date: Fri May 11 10:25:34 2012 -0700 Recognize java enums as constants from source. Fixed up one of the mismatches between how java source is modeled and how java bytecode is modeled. We should get the rest of them too. Closes SI-2764. Looks like this started working in: commit dc6a49337f072686516c14f50b847c38cbc6c225 Author: Miguel Garcia <miguelalfredo.garcia@epfl.ch Date: Fri Jul 6 17:06:57 2012 +0200 GenASM becomes default backend, 1.5 classfiles % (export V=dc6a493; rm *.class; javac -d . test/files/pos/t5165b/TestAnnotation_1.java && scalac-hash $V test/files/pos/t5165b/TestTrait_2.scala && scalac-hash $V test/files/pos/t5165b/TestObject_3.scala) % (export V=dc6a493~1; rm *.class; javac -d . test/files/pos/t5165b/TestAnnotation_1.java && scalac-hash $V test/files/pos/t5165b/TestTrait_2.scala && scalac-hash $V test/files/pos/t5165b/TestObject_3.scala 2>&1 | tail -n 8) self-type TestObject.type does not conform to TestTrait's selftype TestTrait object TestObject extends TestTrait ^ test/files/pos/t5165b/TestObject_3.scala:2: error: TestTrait does not have a constructor object TestObject extends TestTrait ^ two warnings found 5 errors found % for i in 10.0 10.2 10.3 11.0-M8; do (export V=v2.$i; rm *.class; javac -d . test/files/pos/t5165b/TestAnnotation_1.java && scalac-hash $V test/files/pos/t5165b/TestTrait_2.scala && scalac-hash $V test/files/pos/t5165b/TestObject_3.scala); done [warn] v2.11.0-M8 failed, using closest available [warn] v2.11.0-M8 failed, using closest available I've submitted a test case to keep it fixed. This test case used the same compilation order as reported above: https://github.com/scala/scala/pull/3548

            People

            • Assignee:
              Miguel Garcia
              Reporter:
              Bryan Gahagan
            • Votes:
              7 Vote for this issue
              Watchers:
              17 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development