-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Scala Support
Scala support is implemented by the inject-scala-plugin sub-project.
- It is a Scala Compiler Plugin that executes during various phases of compilation similar to the Groovy implementation.
A quick proof of concept project using SBT worked just by adding lines below to build.sbt
file:
resolvers += Resolver.mavenLocal // Needed now since this is not on a central repo anywhere yet
libraryDependencies += "io.micronaut" % "micronaut-runtime" % "2.0.3.BUILD-SNAPSHOT"
addCompilerPlugin("io.micronaut" % "micronaut-inject-scala-plugin" % "2.0.3.BUILD-SNAPSHOT")
import javax.inject.Singleton
import io.micronaut.context.ApplicationContext
@Singleton
class SomeBean {
def getMessage() = "hello world"
}
object Main extends App {
val context = ApplicationContext.run()
println(context.getBean(classOf[SomeBean]).getMessage)
}
-
Features not implemented yet:
- AOP stuff like @Introduction
-
JSR-330 TCK
- Static injection
- Scala does not support package-private methods (or fields) in a identical manner to Java. Injected methods in the RoundThing -> Tire -> SpareTire can not implemented in manner identical to Java. Scala supports "private with with respect to a package".
Java
package org.atinject.tck.auto;
class Tire {...
@Inject void injectPackagePrivateMethod() {...
package org.atinject.tck.auto.accessories;
public class SpareTire extends Tire {...
@Inject void injectPackagePrivateMethod() {
Scala
package org.atinject.tck.auto
class Tire {...
@Inject private[auto] def injectPackagePrivateMethod (): Unit = {...
package org.atinject.tck.auto.accessories
public class SpareTire extends Tire {...
@Inject override private[accessories] def injectPackagePrivateMethod(): Unit = {...
This does not compile since "private[accessories]" is more restrictive than "private[auto]". SpareTire.injectPackagePrivateMethod needs to "private[auto]" which is not the exact equivalent of Java package-private. The scopes in Scala need to overlap and it seems that not injecting the overridden method is correct.
-
A lot of unimplemented code that has not been executed by tests ported over from inject-java-test. In some case Scala's "???" method is used. If the code executes such method and "NotImplementedError" is thrown. The intention is that these failures should occur as tests are ported/developed from the Scala version and desired behavior can be flesh out then.
-
Code needs to refactored to be more idiomatic Scala. Some code was ported over from an equivalent Java implementation and auto-translated into Scala by IntelliJ and was left alone if tests passed. First priority was to make it work.
-
There was some code that was translated over that may not be needed yet. This was done early in development where I was trying emulate too closely what Java or Groovy versions were trying to do. Some of this was just removed.
-
Support for Scala built-in type like List, Option (as opposed to Java Optional).
- Would require modification to AbstractBeanDefinition.getBeanForMethodArgument and getBeanForConstuctorArgument methods. This will be trickier to avoid dependencies on Scala stuff in a non-Scala setting.
-
Dealing different versions of Scala has not been explored yet, like 2.12.x vs 2.13.x not to mention the upcoming Scala 3 (Dotty) release.
-
How does a project using SBT (Scala Build Tool) use this.
-
Problems with @PostContruct and @PreDestroy annotated methods in Scala that throw Exceptions. The Scala version of io.micronaut.inject.close.BeanCloseOrderSpec fails with "java.lang.ClassFormatError: Illegal class name "throws[java/io/IOException]" in class file io/micronaut/inject/close/$CDefinitionClass". This appears to be a problem with micronaut-core generation of the *DefinitionClass.