Part of my learning curve in picking up Kotlin over the last three days was figuring out how to get dependency injection working using CDI (Java EE). I tried lateinit field injection but couldn't seem to get it working.

package net.brandonlamb.calendar.webapi.controllers

import net.brandonlamb.calendar.provider.CalendarService
import net.brandonlamb.calendar.webapi.mapper.orika.CalendarMapper
import net.brandonlamb.common.converters.DateConverter
import net.brandonlamb.common.webapi.controllers.BaseController
import net.brandonlamb.common.webapi.pagination.PagedRequest
import java.util.*
import javax.ejb.Lock
import javax.ejb.LockType.READ
import javax.ejb.Singleton
import javax.inject.Inject
import javax.ws.rs.*
import javax.ws.rs.core.MediaType.APPLICATION_JSON
import javax.ws.rs.core.MediaType.APPLICATION_XML

@Singleton
@Lock(READ)
@Consumes(APPLICATION_JSON, APPLICATION_XML)
@Produces(APPLICATION_JSON, APPLICATION_XML)
open class DateController @Inject constructor(
  val mapper: CalendarMapper,
  val service: CalendarService,
  val pagedRequest: PagedRequest
) : BaseController() {
  @GET
  @Path("/")
  open fun getCalendarDate(
    @PathParam("calendarDate") date: String
  ): Response = Response.ok(
    mapper.map(service.findByDate(DateConverter.toLocalDate(date, 212001), locale))
  ).build()
}

Below are some of my learnings:

  • You must mark EJBs as open as they are proxied
  • You must also mark methods open
  • Use constructor injection with @Inject and constructor(), this seems to work