Skip to content
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

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

Closed
scabug opened this issue Nov 7, 2011 · 12 comments

Comments

@scabug
Copy link

scabug commented Nov 7, 2011

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
@scabug
Copy link
Author

scabug commented Nov 7, 2011

Imported From: https://issues.scala-lang.org/browse/SI-5165?orig=1
Reporter: Bryan Gahagan (bgahagan)
Assignee: @magarciaEPFL
Affected Versions: 2.9.1
See #5699, #2764
Attachments:

  • test.tbz (created on Nov 7, 2011 9:31:58 PM UTC, 416 bytes)

@scabug
Copy link
Author

scabug commented Jan 18, 2012

Alex Black (waterlooalex) said:
Would love to see a fix for this!

@scabug
Copy link
Author

scabug commented Jan 23, 2012

@adriaanm said:
sounds like #2764
please re-open if I missed something

@scabug
Copy link
Author

scabug commented Jan 23, 2012

Lorrin Nelson (lorrin) said:
Well, it is a different error message in a slightly different situation (annotated trait rather than annotated method) and slightly different behavior (rather than a direct compile error, the trait compiles fine but then produces invalid class file; #2764 occurs with single enum in the annotation but this bug only triggers with two).

It seems to me that it is likely but unknown whether fixing #2764 will fix this. If we close this issue, there's no longer any trigger for someone to notice and confirm whether the issue has been resolved or not. So I'd prefer to leave open.

@scabug
Copy link
Author

scabug commented Apr 6, 2012

George (gsward) said:
Are there any updates on getting this fixed. Or does anyone have any suggestion for working around it. Im using JsonTypeInfo to assist with some polymorphic jason mappings.

@scabug
Copy link
Author

scabug commented Apr 6, 2012

George (gsward) said:
I found that i could work around this issue by using a java interface instead of a scala trait

@scabug
Copy link
Author

scabug commented May 7, 2012

@xeno-by said:
In 2.10 scalac TestTrait.scala fails to compile because of:

TestTrait.scala:1: error: annotation argument needs to be a constant; found: TestAnnotation.TestEnumOne.A
@TestAnnotation(one=TestAnnotation.TestEnumOne.A, two=TestAnnotation.TestEnumTwo.C, strVal="something")
                                               ^
TestTrait.scala:1: error: annotation argument needs to be a constant; found: TestAnnotation.TestEnumTwo.C
@TestAnnotation(one=TestAnnotation.TestEnumOne.A, two=TestAnnotation.TestEnumTwo.C, strVal="something")
                                                                                 ^
two errors found

@scabug
Copy link
Author

scabug commented May 11, 2012

@paulp said:
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.

@scabug
Copy link
Author

scabug commented May 12, 2012

@soc said:
The problem with the class-parser is probably related to #5699.

@scabug
Copy link
Author

scabug commented Oct 5, 2012

Raman Gupta (rocketraman) said:
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.

@scabug
Copy link
Author

scabug commented Jan 29, 2014

@adriaanm said:
Compiles with scalac 2.11.0-M8

@scabug scabug closed this as completed Jan 29, 2014
@scabug
Copy link
Author

scabug commented Feb 18, 2014

@retronym said:
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: scala/scala#3548

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant