-
Notifications
You must be signed in to change notification settings - Fork 21
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
incorrect bytecode generated for inner objects #1572
Comments
Imported From: https://issues.scala-lang.org/browse/SI-1572?orig=1
|
@paulp said: scala> Class.forName("a$$foo$$$$anonfun$$bar$$1").getDeclaringClass
java.lang.NoClassDefFoundError: a$$foo
at java.lang.Class.getDeclaringClass(Native Method)
scala> Class.forName("b$$foo$$$$anonfun$$bar$$2").getDeclaringClass
res2: java.lang.Class[_] = class b$$foo |
@paulp said: |
Lalit Pant (lpant) said: I see two problems here in the generated class-files:
More details below: == Problem 1 - Incorrect !InnerClasses attributes == object OneLevelOuter {
def bar = List(1,2).map(_*2)
}
object TwoLevelOuter {
object Outer {
def bar = List(1,2).map(_*2)
}
} Here, !OneLevelOuter$$.class has an !InnerClasses attribute with the following information:[[BR]] !TwoLevelOuter$$Outer$$.class has an !InnerClasses attribute with the following information:[[BR]] == Problem 2 - Incorrect Method Signature attributes involving Scala.Nothing and Scala.Null == This code demonstrates the problem: object MethodSig {
val Empty = new collection.immutable.Stack[Nothing]
def m1: Nothing = {
throw new RuntimeException()
}
} This translates to the following in the classfile for !MethodSig$$: A method called Empty with:[[BR]] A method called m1 with:[[BR]] As you can see, Nothing is referenced correctly in the Descriptor for m1, but not in the Signature for Empty. |
@SethTisue said: |
@SethTisue said: |
@dragos said: If I am not mistaken, InnerClasses attributes have to be consistent across a JVM, so the same class cannot appear as having different outer classes in different class files. I don't see a good solution to this, so I am open to suggestions. |
@dragos said: |
@paulp said:
Not that I think pursuing inconsistency is the way to go, but the spec says "The Java virtual machine does not currently check the consistency of the InnerClasses attribute with any class file actually representing a class or interface referenced by the attribute." http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.htmlSI-79996 Although I'm not sure it and you are talking about the same thing. With respect to this issue, I would say anytime "using scala from java" comes into conflict with other reasonable goals, "using scala from java" should lose out, especially if it's just "using scala from java with pretty names." (I do think "using java from scala" should be a high priority.) |
@dragos said:
I vaguely remember having tried to set the outer class to be the current class, so I think this is quite easy to hack, but I am a bit short on time until next week. If someone here is ready to do it, I can point out relevant pieces of code.
Agreed. So you would make inner classes member of the module class, and live with '$$' names in Java? That was the way it worked some time ago, then it was 'fixed' to support nicer names for inner classes. I don't remember all the arguments, but we should check at least #1126 before doing the change. |
@paulp said: |
@dragos said: I had to fix another problem with the way java signatures were generated, but now proguard is happy with the scala compiler bytecode, except for two warnings about reflective calls in the interpreter. The fix is in r18618. |
@SethTisue said: |
Paul LaCrosse (pjlacrosse) said:
It is not limited to the Scala library, but shows up for user classes: [proguard] Warning: com.test.app.abc.data.QueryDtl$$: can't find referenced class com.test.app.abc.data.QueryDtl$$$$anonfun$$apply$$1 |
@paulp said:
Please supply us with something more concrete than an error message if you want this to have any chance of being investigated. It's quite frustrating when people expend so little effort making a report. |
Paul LaCrosse (pjlacrosse) said: |
Given the following test code:
...the generated bytecode for a$$foo$$ contains references to the non-existent a$$foo, as does the anon function generated for the map. In the case of b (which defines a class of the same name as the object) the references incorrectly point to the class instead of the object. This can be seen by way of reflection:
I came across this attempting to use proguard on the scala jars. It objects to processing them because of inconsistent InnerClasses attributes due to the above issue - for instance there are references to the non-existent class scala/tools/nsc/symtab/Definitions$$definitions .
The text was updated successfully, but these errors were encountered: