Null-Checks and javax.inject.Inject


#1

Given the following extract from a ejb singleton bean:

import javax.annotation.PostConstruct as postConstruct import javax.inject.Inject as inject import javax.ejb.Singleton as singleton import javax.ejb.Startup as startup

singleton startup

class ExampleBean {   inject var log: Logger? = null

  postConstruct
  public fun doIt() {
  log!!.info(“a log string”)
  }

  //... }

Although I know that the injected log will practically never be null, I still have to declare it as a var and as nullable. As a result I have to safeguard every single access. Is there a pattern to make this a bit more elegant? I was trying to use Constructor injection instead but no luck:

WELD-000816 Cannot determine constructor to use for public final@Singleton @JetClass @Startup class …ExampleBean

#2

The part about constructor injection with EJB session beans is now clearer: The EJB 3.1 spec, section 4.9.2 states

The class must have a public constructor that takes no parameters.

Using Kotlin, this means having either a constructor taking no parameters or having a constructor with all parameters defaulted. Either way, that does not free us from the unnecessary !! checks.

Next I was trying to get rid of the null checks using a CDI Bean. Goal: have a constructor which frees us from null checks like

inject class ExampleBean(val log: Logger) {

I could not get this to work. When using constructor injection, I had to default all parameters to make it pass the cdi checks. Finally, cdi chose the default constructor and nothing was injected.

This thread was helpful http://stackoverflow.com/questions/9173592/can-i-use-cdi-constructor-injection-for-ejbs


#3

Currently there's no workaround for this problem better than having an extra property:

``

inject var _p: Foo? = null
var p: Foo
  get() = _p!!
  set(v) { _p = v }

We are working on a better alternative.


#4

do you have an issue for that? I would create one otherwise.


#5

I think there is one


#6

Do you have some new sollution for this problem?


#7

Yes, we now have late-initialized properties. It’s possible to declare one with the lateinit modifier:

lateinit var p: Foo
    @Inject set

#8

Thank you for answer. Works great!


#9

If you are starting a new project in Kotlin and not carrying over existing use of Dagger, I would recommend looking at Kodein which is DI written specifically for Kotlin: https://github.com/SalomonBrys/Kodein