codingwell / scala-guice

Scala extensions for Google Guice
Apache License 2.0
341 stars 44 forks source link

ScalaModule#bind[static nested class of an inner class] cannot find inner class #93

Closed mosesn closed 4 years ago

mosesn commented 4 years ago

So we found a weird corner-case that seems to fail in the new scala-guice world. I'm not sure when this issue was introduced, but it was probably in the manifest => typetags transition.

Here is the most minimal repro I have:

scala:

import com.google.inject.{AbstractModule, Guice}
import net.codingwell.scalaguice.ScalaModule
import MyInterface.Bar.Foo

object Main extends App {
  val injector = Guice.createInjector(new AbstractModule with ScalaModule {
    override def configure(): Unit = {
      bind[Foo]
    }
  })
}

java:

interface MyInterface {
  public class Bar {
    public static class Foo {

    }
  }
}

And here's the error message we got:

[error] (run-main-8) java.lang.ClassNotFoundException: no Java class corresponding to class Bar found
[error] java.lang.ClassNotFoundException: no Java class corresponding to class Bar found
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror.noClass$1(JavaMirrors.scala:1258)
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror.$anonfun$classToJava$3(JavaMirrors.scala:1296)
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror.$anonfun$classToJava$1(JavaMirrors.scala:1296)
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror$$Lambda$5644/614486484.apply(Unknown Source)
[error]         at scala.reflect.runtime.TwoWayCaches$TwoWayCache.$anonfun$toJava$1(TwoWayCaches.scala:61)
[error]         at scala.reflect.runtime.TwoWayCaches$TwoWayCache.toJava(TwoWayCaches.scala:57)
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror.classToJava(JavaMirrors.scala:1257)
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror.runtimeClass(JavaMirrors.scala:229)
[error]         at scala.reflect.runtime.JavaMirrors$JavaMirror.runtimeClass(JavaMirrors.scala:68)
[error]         at net.codingwell.scalaguice.TypeConversions$.findOwnerOf(TypeConversions.scala:106)
[error]         at net.codingwell.scalaguice.TypeConversions$.scalaTypeToJavaType(TypeConversions.scala:70)
[error]         at net.codingwell.scalaguice.package$.typeLiteral(package.scala:37)
[error]         at net.codingwell.scalaguice.InternalModule$BindingBuilder.<init>(ScalaModule.scala:70)
[error]         at net.codingwell.scalaguice.InternalModule.bind(ScalaModule.scala:75)
[error]         at net.codingwell.scalaguice.InternalModule.bind$(ScalaModule.scala:75)
[error]         at Main$$anon$1.bind(Main.scala:6)
[error]         at Main$$anon$1.configure(Main.scala:8)
[error]         at com.google.inject.AbstractModule.configure(AbstractModule.java:61)
[error]         at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:347)
[error]         at com.google.inject.spi.Elements.getElements(Elements.java:104)
[error]         at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:137)
[error]         at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:105)
[error]         at com.google.inject.Guice.createInjector(Guice.java:87)
[error]         at com.google.inject.Guice.createInjector(Guice.java:69)
[error]         at com.google.inject.Guice.createInjector(Guice.java:59)
[error]         at Main$.delayedEndpoint$Main$1(Main.scala:6)
[error]         at Main$delayedInit$body.apply(Main.scala:5)
[error]         at scala.Function0.apply$mcV$sp(Function0.scala:39)
[error]         at scala.Function0.apply$mcV$sp$(Function0.scala:39)
[error]         at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
[error]         at scala.App.$anonfun$main$1$adapted(App.scala:80)
[error]         at scala.App$$Lambda$5446/1686148356.apply(Unknown Source)
[error]         at scala.collection.immutable.List.foreach(List.scala:392)
[error]         at scala.App.main(App.scala:80)
[error]         at scala.App.main$(App.scala:78)
[error]         at Main$.main(Main.scala:5)
[error]         at Main.main(Main.scala)
[error]         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error]         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error]         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.lang.reflect.Method.invoke(Method.java:497)
[error] stack trace is suppressed; run 'last Compile / bgRun' for the full output

This isn't urgent for us, we worked around it by refactoring (turned out they didn't really need static nested class of an inner class lol), but I thought it would be good to let you know. If you have a good tip for how to patch this, I'm happy to take a stab it.

tsuckow commented 4 years ago

I "fixed" it in 4.2.11, but I'll say it is more of a sidestep. I think there are still cases that are broken and may be even less obvious now. That said, they are probably exceedingly rare so we'll deal with it when it comes up.

mosesn commented 4 years ago

@tsuckow thank you! let me try updating and see if it fixes the problem after I apply the revert.

mosesn commented 4 years ago

yep, works for us, thank you!