Open
Description
Compiler version
3.3.6 and 3.7.0
Minimized code
The following code will compile, and its test (logadapter.test.Test
) will run fine. (Try it as-is in scala-cli
. There are no external dependencies.)
However, if the logadapter.test
package is placed in a separate module, then compiled separately against the rest, a java.lang.AbstractMethodError
results when the test program is run. (Try out this sbt project.)
package logadapter:
trait AbstractLogAdapter:
def info( message : String ) : Unit
trait AbstractApi[T <: AbstractLogAdapter]:
def logAdapterFor( loggerName : String ) : T
trait SelfLogging:
given adapter : T = logAdapterFor(this.getClass.getName)
object Api extends logadapter.AbstractApi[LogAdapter]:
def logAdapterFor( loggerName : String ) : LogAdapter = new LogAdapter( loggerName )
class LogAdapter( loggerName : String ) extends logadapter.AbstractLogAdapter:
def info( message : String ) : Unit = System.err.println( s"INFO [${loggerName}] ${message}" )
package logadapter.test:
object Test extends logadapter.Api.SelfLogging:
def main(args : Array[String]) : Unit =
summon[logadapter.LogAdapter].info("Hello")
Output
When the (test) application code is compiled separately from the test code, something like the following results. (Line numbers will be off, since I've had to bring the test code into a separate file.)
java.lang.AbstractMethodError: Receiver class logadapter.test.Test$ does not define or inherit an implementation of the resolved method 'abstract logadapter.AbstractApi logadapter$AbstractApi$SelfLogging$$$outer()' of interface logadapter.AbstractApi$SelfLogging.
at logadapter.AbstractApi$SelfLogging.adapter(core.scala:9)
at logadapter.AbstractApi$SelfLogging.adapter$(core.scala:8)
at logadapter.test.Test$.adapter$lzyINIT1(core.scala:3)
at logadapter.test.Test$.adapter(core.scala:3)
at logadapter.test.Test$.main(core.scala:5)
at logadapter.test.Test.main(core.scala)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at sbt.Run.invokeMain(Run.scala:135)
at sbt.Run.execute$1(Run.scala:85)
at sbt.Run.$anonfun$runWithLoader$5(Run.scala:112)
at sbt.Run$.executeSuccess(Run.scala:178)
at sbt.Run.runWithLoader(Run.scala:112)
at sbt.Defaults$.$anonfun$bgRunTask$6(Defaults.scala:2072)
at sbt.Defaults$.$anonfun$termWrapper$2(Defaults.scala:2011)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
at scala.util.Try$.apply(Try.scala:213)
at sbt.internal.BackgroundThreadPool$BackgroundRunnable.run(DefaultBackgroundJobService.scala:378)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Expectation
Whether the test application is compiled separately or together with the "library" code, I expect the same output:
INFO [logadapter.test.Test$] Hello