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

JVM crashes when reflecting a Scala class with a Java annotation with a nested enumeration type #6548

Closed
scabug opened this issue Oct 20, 2012 · 5 comments

Comments

@scabug
Copy link

scabug commented Oct 20, 2012

Given the following Java annotation:

// Anno.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD,
    ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Anno
{
    public Value value() default Value.VALUE;

    public enum Value
    {
        VALUE;
    }
}

An the following Scala class:

// Bean.scala
import reflect.runtime.currentMirror

class Bean {
  @Anno(Anno.Value.VALUE)
  def value = 1
}

object Bean extends App {
  currentMirror.classSymbol(classOf[Bean]).isCaseClass
  
}

Under a recent 2.10.0 snapshot, compilation succeeds, but running Bean.scala in the code runner produces this crash:

$ javac Anno.java
$ scalac Bean.scala
$ scala Bean
scala.reflect.internal.FatalError: bad symbolic reference to value Value in object Anno (a classfile may be missing)
	at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:48)
	at scala.reflect.internal.SymbolTable.globalError(SymbolTable.scala:47)
	at scala.reflect.internal.Symbols$StubSymbol$class.fail(Symbols.scala:3110)
	at scala.reflect.internal.Symbols$StubSymbol$class.info(Symbols.scala:3123)
	at scala.reflect.internal.Symbols$StubTermSymbol.info(Symbols.scala:3132)
	at scala.reflect.internal.Symbols$StubTermSymbol.info(Symbols.scala:3132)
	at scala.reflect.internal.pickling.UnPickler$Scan.scala$reflect$internal$pickling$UnPickler$Scan$$fromName$1(UnPickler.scala:207)
	at scala.reflect.internal.pickling.UnPickler$Scan.readExtSymbol$1(UnPickler.scala:226)
	at scala.reflect.internal.pickling.UnPickler$Scan.readSymbol(UnPickler.scala:245)
	at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolRef(UnPickler.scala:778)
	at scala.reflect.internal.pickling.UnPickler$Scan.readConstant(UnPickler.scala:416)
	at scala.reflect.internal.pickling.UnPickler$Scan$$anonfun$readClassfileAnnotArg$3.apply(UnPickler.scala:454)
	at scala.reflect.internal.pickling.UnPickler$Scan$$anonfun$readClassfileAnnotArg$3.apply(UnPickler.scala:454)
	at scala.reflect.internal.pickling.UnPickler$Scan.at(UnPickler.scala:171)
	at scala.reflect.internal.pickling.UnPickler$Scan.readClassfileAnnotArg(UnPickler.scala:454)
	at scala.reflect.internal.pickling.UnPickler$Scan.readAnnotationInfo(UnPickler.scala:468)
	at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolAnnotation(UnPickler.scala:486)
	at scala.reflect.internal.pickling.UnPickler$Scan.run(UnPickler.scala:88)
	at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:37)
	at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:561)
	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.complete(SymbolLoaders.scala:31)
	at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1217)
	at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1349)
	at scala.reflect.internal.Symbols$Symbol.hasFlag(Symbols.scala:603)
	at scala.reflect.internal.Symbols$ClassSymbol.isCaseClass(Symbols.scala:2864)
	at Bean$delayedInit$body.apply(Bean.scala:10)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:71)
	at scala.App$$anonfun$main$1.apply(App.scala:71)
	at scala.collection.immutable.List.foreach(List.scala:309)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
	at scala.App$class.main(App.scala:71)
	at Bean$.main(Bean.scala:9)
	at Bean.main(Bean.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.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
	at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
	at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
	at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
	at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
	at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
	at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
	at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
	at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
	at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
java.lang.RuntimeException: error reading Scala signature of Bean: bad symbolic reference to value Value in object Anno (a classfile may be missing)
	at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:45)
	at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:561)
	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.complete(SymbolLoaders.scala:31)
	at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1217)
	at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1349)
	at scala.reflect.internal.Symbols$Symbol.hasFlag(Symbols.scala:603)
	at scala.reflect.internal.Symbols$ClassSymbol.isCaseClass(Symbols.scala:2864)
	at Bean$delayedInit$body.apply(Bean.scala:10)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:71)
	at scala.App$$anonfun$main$1.apply(App.scala:71)
	at scala.collection.immutable.List.foreach(List.scala:309)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
	at scala.App$class.main(App.scala:71)
	at Bean$.main(Bean.scala:9)
	at Bean.main(Bean.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.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
	at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
	at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
	at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
	at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
	at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
	at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
	at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
	at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
	at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
@scabug
Copy link
Author

scabug commented Oct 20, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6548?orig=1
Reporter: Christopher Currie (codemonkey)
Affected Versions: 2.10.0-RC2, 2.10.0
Attachments:

  • Bean.zip (created on Oct 20, 2012 5:15:46 PM UTC, 4832 bytes)

@scabug
Copy link
Author

scabug commented Oct 20, 2012

@paulp said:
The "object Anno" needs a member "object Value" which it has not been given. Either that or we need to do better at being flexible when someone uses a path involving java classes, and treat the dots as type selections when necessary and valid in java.

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[Anno].declarations
res1: reflect.runtime.universe.MemberScope = SynchronizedOps(class Value, object Value, method value)

// Geez, is this really the most direct route to the type of the companion
scala> typeOf[Anno].typeSymbol.companionSymbol.typeSignature.declarations
res2: reflect.runtime.universe.MemberScope = SynchronizedOps(class Value)

@scabug
Copy link
Author

scabug commented Dec 7, 2012

@xeno-by said:
scala/scala#1727

@scabug scabug closed this as completed Dec 19, 2012
@scabug
Copy link
Author

scabug commented Dec 19, 2012

@paulp said:
f274490

@scabug
Copy link
Author

scabug commented Feb 9, 2013

@adriaanm said (edited on Feb 9, 2013 9:48:20 PM UTC):
Due to binary compatibility restrictions, this cannot go into 2.10.1-RC1.

See scala/scala#2103.

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

2 participants