1

Trying to create a custom @Context I can inject into my resources via Jersey.

This is covered in Java in this question. I've read the docs covering this which are also in Java. And lastly some code covering the same topic (doing this all through Dropwizard) in Github.

The first part is creating the Factory.

Scala:

import org.glassfish.hk2.api.Factory
import javax.inject.Inject
import javax.ws.rs.container.ContainerRequestContext
import MyObj

class MyObjFactory @Inject()(ctr: ContainerRequestContext) extends Factory[MyObj] {
  private final val context: ContainerRequestContext = ctr

  override def provide(): MyObj = context.getProperty("myObj").asInstanceOf[MyObj]

  override def dispose(myObj: MyObj): Unit = { }
}

The next part is registering the factory, where I make an assumption that classOf[T] is the appropriate Scala equivalent to Java's T.class

import org.glassfish.hk2.utilities.binding.AbstractBinder

environment.jersey.register(new AbstractBinder {
  override def configure(): Unit = {
    bindFactory(classOf[MyObjFactory])
        .to(classOf[MyObj])
        .proxy(true)
        .proxyForSameScope(false)
        .in(classOf[RequestScoped])
  }
})

Last should be the actual injection:

@Path("/")
class MyResource {
    @GET
    def get(@Context uriInfo: UriInfo, @Context myObjFactory: MyObjFactory) = {
        // do stuff
    }
}

This all compiles but fails at runtime with the following exception

ERROR [2017-04-05 00:26:14,605] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: 8e5877857c823fef
! java.lang.IllegalArgumentException: Invalid injectee with required type of null passed to getInjecteeDescriptor
! ... 87 common frames omitted
! Causing: org.glassfish.hk2.api.MultiException: A MultiException has 1 exceptions.  They are:
! 1. java.lang.IllegalArgumentException: Invalid injectee with required type of null passed to getInjecteeDescriptor
! 
! at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetInjecteeDescriptor(ServiceLocatorImpl.java:545)
! at org.jvnet.hk2.internal.ServiceLocatorImpl.getInjecteeDescriptor(ServiceLocatorImpl.java:584)
! at org.glassfish.jersey.internal.inject.ContextInjectionResolver$1.compute(ContextInjectionResolver.java:102)
! at org.glassfish.jersey.internal.inject.ContextInjectionResolver$1.compute(ContextInjectionResolver.java:98)
! at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)

Can't tell if I am making a mistake with my conversion to Scala or I've done something wrong actually registering the Binder.

Community
  • 1
  • 1
diplosaurus
  • 2,538
  • 5
  • 25
  • 53

1 Answers1

2
get(@Context uriInfo: UriInfo, @Context myObjFactory: MyObjFactory) <===

You're trying to inject the Factory. The Factory is used to create the service. It is not meant to be injected in this case. What you want to inject is the actual service, and the factory will be used to create it behind the scene

get(@Context uriInfo: UriInfo, @Context myOb: MyObj) <===
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Good call, though that still failed with a runtime error - I have updated to reflect your recommendation. – diplosaurus Apr 05 '17 at 17:54
  • Actually I just removed the `.proxy(true)` and `.proxyForSameScope(false` methods and got everything working. Not sure if those are important but I appreciate the help! – diplosaurus Apr 05 '17 at 18:02
  • 1
    Glad you got it working. FYI, please don't make edits to your post like that one. What you've done is just invalidated my answer. If you want to add new content to your post, then do just that, _add_ it, dont reeplace previous content. Just put a little "Edit" at the bottom, then add the new content below it – Paul Samsotha Apr 05 '17 at 20:50