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

Compiler barfs on source referring to class which refers to an annotation class not on the classpath

    Details

      Description

      Given a simple java class with an annotation:

      @Foo
      public class FooBean {
          ...
      }
      

      FooBean is already compiled and available on the compiler classpath.

      when attempting to compile some scala code that instantiates/uses the FooBean class when the Foo annotation class is not accessible on the compiler's classpath but FooBean is, the scala compiler gives me a "Missing dependency" error:

      scala> new FooBean
      error: error while loading FooBean, Missing dependency 'class package.to.Foo', required by /home/raman/test/jars/foobean.jar(FooBean.class)
      <console>:8: error: FooBean does not have a constructor
                    new FooBean
      

      This seems very similar to SI-1135, the fix for which should be in 2.9.1. This also seems similar to SI-5343, which is marked as Fixed and will be in 2.10.x. However, as per Jason Zaugg on the users mailing list, this issue will still occur even with the fix for SI-5343.

      I have verified this by checking this on Scala 2.10.0.M1, and get the following error:

      scala> new FooBean
      warning: Class package.to.Foo not found - continuing with a stub.
      java.lang.AssertionError: assertion failed: package.to.Foo
              at scala.Predef$.assert(Predef.scala:160)
              at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:946)
              at scala.reflect.internal.Symbols$TypeSymbol.isNonBottomSubClass(Symbols.scala:2324)
              at scala.reflect.internal.AnnotationInfos$AnnotationInfo.matches(AnnotationInfos.scala:220)
              at scala.reflect.internal.AnnotationInfos$Annotatable$$anonfun$hasAnnotation$1.apply(AnnotationInfos.scala:37)
              at scala.reflect.internal.AnnotationInfos$Annotatable$$anonfun$hasAnnotation$1.apply(AnnotationInfos.scala:37)
              at scala.collection.LinearSeqOptimized$class.exists(LinearSeqOptimized.scala:79)
              at scala.collection.immutable.List.exists(List.scala:76)
              at scala.reflect.internal.AnnotationInfos$Annotatable$class.hasAnnotation(AnnotationInfos.scala:37)
              at scala.reflect.internal.Symbols$Symbol.hasAnnotation(Symbols.scala:71)
              at scala.reflect.internal.Symbols$Symbol.isDeprecated(Symbols.scala:533)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.checkDeprecated(RefChecks.scala:1275)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.scala$tools$nsc$typechecker$RefChecks$RefCheckTransformer$$checkTypeRef(RefChecks.scala:1379)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$24.apply(RefChecks.scala:1581)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$24.apply(RefChecks.scala:1577)
              at scala.reflect.internal.Types$ForEachTypeTraverser.traverse(Types.scala:4331)
              at scala.reflect.internal.Types$Type.foreach(Types.scala:708)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.doTypeTraversal(RefChecks.scala:1388)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1577)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$4.apply(Trees.scala:1156)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$4.apply(Trees.scala:1155)
              at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:1271)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1154)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStat(RefChecks.scala:1226)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
              at scala.collection.immutable.List.foreach(List.scala:76)
              at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:243)
              at scala.collection.AbstractTraversable.flatMap(Traversable.scala:112)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:107)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1174)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:1248)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$2.apply(Trees.scala:1146)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$2.apply(Trees.scala:1145)
              at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:1271)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1144)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1246)
              at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1246)
              at scala.collection.immutable.List.loop$1(List.scala:150)
              at scala.collection.immutable.List.mapConserve(List.scala:166)
              at scala.reflect.api.Trees$Transformer.transformTrees(Trees.scala:1246)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.eliminateModuleDefs(RefChecks.scala:1185)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStat(RefChecks.scala:1224)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
              at scala.collection.immutable.List.foreach(List.scala:76)
              at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:243)
              at scala.collection.AbstractTraversable.flatMap(Traversable.scala:112)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:107)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1174)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:1248)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$2.apply(Trees.scala:1146)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$2.apply(Trees.scala:1145)
              at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:1271)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1144)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1246)
              at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1246)
              at scala.collection.immutable.List.loop$1(List.scala:150)
              at scala.collection.immutable.List.mapConserve(List.scala:166)
              at scala.reflect.api.Trees$Transformer.transformTrees(Trees.scala:1246)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.eliminateModuleDefs(RefChecks.scala:1185)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStat(RefChecks.scala:1224)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
              at scala.collection.immutable.List.foreach(List.scala:76)
              at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:243)
              at scala.collection.AbstractTraversable.flatMap(Traversable.scala:112)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:107)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1174)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:1248)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$2.apply(Trees.scala:1146)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$2.apply(Trees.scala:1145)
              at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:1271)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1144)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1246)
              at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1246)
              at scala.collection.immutable.List.loop$1(List.scala:150)
              at scala.collection.immutable.List.mapConserve(List.scala:166)
              at scala.reflect.api.Trees$Transformer.transformTrees(Trees.scala:1246)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.eliminateModuleDefs(RefChecks.scala:1185)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStat(RefChecks.scala:1224)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$transformStats$1.apply(RefChecks.scala:1139)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:243)
              at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
              at scala.collection.immutable.List.foreach(List.scala:76)
              at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:243)
              at scala.collection.AbstractTraversable.flatMap(Traversable.scala:112)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformStats(RefChecks.scala:107)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1140)
              at scala.reflect.api.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1140)
              at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:1271)
              at scala.reflect.api.Trees$Transformer.transform(Trees.scala:1139)
              at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1632)
              at scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:225)
              at scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:30)
              at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:386)
              at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:355)
              at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:349)
              at scala.collection.Iterator$class.foreach(Iterator.scala:687)
              at scala.collection.AbstractIterator.foreach(Iterator.scala:1112)
              at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:349)
              at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1130)
              at scala.tools.nsc.Global$Run.compileSources(Global.scala:1105)
              at scala.tools.nsc.interpreter.IMain.compileSourcesKeepingRun(IMain.scala:445)
              at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compileAndSaveRun(IMain.scala:835)
              at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compile(IMain.scala:789)
              at scala.tools.nsc.interpreter.IMain$Request.compile(IMain.scala:953)
              at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:616)
              at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:583)
              at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:777)
              at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:828)
              at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:734)
              at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:598)
              at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:605)
              at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:608)
              at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:905)
              at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:870)
              at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:870)
              at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:155)
              at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:870)
              at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:79)
              at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:92)
              at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
              at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
      
      That entry seems to have slain the compiler.  Shall I replay
      your session? I can re-run each line except the last one.
      [y/n]
      

        Issue Links

          Activity

          Hide
          Paul Phillips added a comment -

          This could probably be made robust, but I don't think it's safe. There are things like the continuations plugin where annotations aren't merely decorative, and if we ignore the inability to load an annotation class I think we risk miscompiling. I am unsure.

          Show
          Paul Phillips added a comment - This could probably be made robust, but I don't think it's safe. There are things like the continuations plugin where annotations aren't merely decorative, and if we ignore the inability to load an annotation class I think we risk miscompiling. I am unsure.
          Hide
          Raman Gupta added a comment -

          Couple of notes: javac compiles in this case without any issues. Secondly, and I am a scala newb so I may be wrong here, but wouldn't plugins like the continuation plugin only apply to the source being compiled, not to sources that have already been compiled and are already in ".class" form?

          Show
          Raman Gupta added a comment - Couple of notes: javac compiles in this case without any issues. Secondly, and I am a scala newb so I may be wrong here, but wouldn't plugins like the continuation plugin only apply to the source being compiled, not to sources that have already been compiled and are already in ".class" form?
          Hide
          Jason Zaugg added a comment -

          Ideally the failure would be deferred until the time that the compiler plugin tried to access a particular named annotation.

          Show
          Jason Zaugg added a comment - Ideally the failure would be deferred until the time that the compiler plugin tried to access a particular named annotation.
          Hide
          James Iry added a comment -

          2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.

          Show
          James Iry added a comment - 2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.

            People

            • Assignee:
              Simon Ochsenreither
              Reporter:
              Raman Gupta
            • Votes:
              1 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:

                Development