How to make a Java-injectable field?


#1

Platform types are welcome indeed. I am experimenting now with writing a web app using the Ninja Framework (http://www.ninjaframework.org/) in Kotlin. The Java to Kotlin converter has worked well!

But, one thing did not convert, a Java field with the guice @Inject annotation. This is where reflection is used to automagically insert the right object. As this should never be null, I did not want to declare it as possibly null, but had to because using Delegates.nonNull creates a complex Kotlin specific object at the Java ABI level.

This leads me to wonder why the syntax for platform types is not usable in the program itself. In the talks about generics you mentioned that having syntax that only appears in IDE and compiler messages is not great, but here we have exactly that. I could solve my problem if only Kotlin let me specify the type of this field as a platform type.


#2

This leads me to wonder why the syntax for platform types is not usable in the program itself. In the talks about generics you mentioned that having syntax that only appears in IDE and compiler messages is not great, but here we have exactly that. I could solve my problem if only Kotlin let me specify the type of this field as a platform type.

Are you sure it was us and not the Ceylon guys? :) Anyway, this is another tradeoff: having platform types available for the user gives more freedom and more responsibility, and as far as language design goes, we have to balance the two. If it proves to be necessary, we'll make them available, but as long as we can avoid doing so, we will.

Back to the main point: the case you are describing has been brought up before, we are investigating the possible solutions, inluding dedicated annotations and generalization of the property delegayion mechanism. Thanks for the report!


#3

mikehearn ha scritto:

Platform types are welcome indeed. I am experimenting now with writing a web app using the Ninja Framework (http://www.ninjaframework.org/) in Kotlin. The Java to Kotlin converter has worked well!

But, one thing did not convert, a Java field with the guice @Inject annotation. This is where reflection is used to automagically insert the right object. As this should never be null, I did not want to declare it as possibly null, but had to because using Delegates.nonNull creates a complex Kotlin specific object at the Java ABI level.

This leads me to wonder why the syntax for platform types is not usable in the program itself. In the talks about generics you mentioned that having syntax that only appears in IDE and compiler messages is not great, but here we have exactly that. I could solve my problem if only Kotlin let me specify the type of this field as a platform type.


many frameworks allow to annotate fields inside constructors. e.g., consider Spring:

EnableAutoConfiguration public class Application [Autowired] internal(val repository: CustomerRepository) : CommandLineRunner {

here I am annotating the internal constructor with [AutoWired] so that the non-null CustomerRepository is injected at construction time. The same should be doable using javax @Inject http://docs.oracle.com/javaee/7/api/javax/inject/Inject.html (I am assuming ninja is implementing that), and AFAIR that should also be the suggested way to do DI, since that way your injected field can be marked as final (or in Kotlin, a val)

This is more elegant, and lets you do away with explicit platform types

HTH


#4

Oh, it might have been Ceylon yes :)  That'd make more sense, with their intersection/union types idea.


#5

Ninja is using Guice under the hood, and DI frameworks have never really been my cup of tea so I didn't think of that. I will have to try it, thanks!


#6

I believe in most cases DI frameworks allow to annotate constructor parameters, which (IIRC) is actually the preferred way. I believe that kotlin guidelines should just advise to do that (see my other post)

Besides, annotating fields is often regarded as an anti-pattern:

http://stackoverflow.com/questions/10057239/is-this-a-guice-anti-pattern
https://github.com/google/guice/wiki/Injections


#7

Works great! I got confused for a moment because I was trying to use the annotation without the square brackets, which didn't work. But now I got it.

Seems like that should be in the FAQ or noted elsewhere in the docs, but I think I’ll wait until decisions were made on my outstanding doc patches before doing new ones. The Kotlin docs need a clear policy on where language/platform specific stuff goes (as I guess, DI frameworks are out of scope for javascript).