users@jersey.java.net

Re: [Jersey] Guice access to Jersey-created objects

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Mon, 17 Aug 2009 17:46:43 -0700

Paul Sandoz wrote:
> On Aug 14, 2009, at 10:44 PM, Richard Wallace wrote:
>>
>> But I'm not convinced that will solve your problem either. It sounds
>> more like the WebApplication instance that is being created by Guice
>> is not the one that is being used by Jersey. You said it's a Java SE
>> app and so doesn't use any of the servlet stuff. But however you are
>> kicking off Jersey, whether creating a GrizzlyContainer or something
>> else, you'll need to be sure it uses the WebApplication instance Guice
>> creates.
>>
>
> Yes, that could be it.
>
> Craig, if you are using the low-level Grizzly support with Adapter and
> ContainerFactory then it is not currently possible to obtain the
> WebApplication instance that is utilized:
Thanks for the confirmation ... I was just coming to that conclusion.
>
> public final class ContainerFactory {
>
> ...
>
> public static <A> A createContainer(Class<A> type, ResourceConfig
> resourceConfig,
> IoCComponentProviderFactory factory)
> throws ContainerException, IllegalArgumentException {
> WebApplication wa = WebApplicationFactory.createWebApplication();
>
> // Reverse the order so that applications may override
> LinkedList<ContainerProvider> cps = new
> LinkedList<ContainerProvider>();
> for (ContainerProvider cp :
> ServiceFinder.find(ContainerProvider.class, true))
> cps.addFirst(cp);
>
> for (ContainerProvider<A> cp : cps) {
> A c = cp.createContainer(type, resourceConfig, wa);
> if (c != null) {
> // Initiate the web application
> if (!wa.isInitiated()) {
> wa.initiate(resourceConfig, factory);
> }
>
> // Register a container listener
> Object o = resourceConfig.getProperties().get(
> ResourceConfig.PROPERTY_CONTAINER_NOTIFIER);
> if (o instanceof ContainerNotifier &&
> c instanceof ContainerListener) {
> ContainerNotifier crf = (ContainerNotifier)o;
> crf.addListener((ContainerListener)c);
> }
> return c;
> }
> }
>
> throw new IllegalArgumentException("No container provider
> supports the type " + type);
> }
>
>
> public class GrizzlyContainerProvider implements
> ContainerProvider<Adapter> {
>
> public GrizzlyContainerProvider() {
> Class<?> c = Adapter.class;
> }
>
> public Adapter createContainer(Class<Adapter> type,
> ResourceConfig resourceConfig,
> WebApplication application) throws ContainerException {
> if (type != Adapter.class)
> return null;
>
> return new GrizzlyContainer(application);
> }
> }
>
>
> One possible solution is to create your own ContainerProvider that
> reuses GrizzlyContainerProvider and returns an Adapter and the
> WebApplication. Or create your own ContainerFactory
>
> public class WebAppGrizzlyContainerProvider implements
> ContainerProvider<MyType> {
>
> public MyType createContainer(Class<Adapter> type,
> ResourceConfig resourceConfig,
> WebApplication application) throws ContainerException {
> if (type != MyType.class)
> return null;
>
> // Reverse the order so that applications may override
> LinkedList<ContainerProvider> cps = new
> LinkedList<ContainerProvider>();
> for (ContainerProvider cp :
> ServiceFinder.find(ContainerProvider.class, true))
> cps.addFirst(cp);
>
> for (ContainerProvider<Adapter> cp : cps) {
> Adapter c = cp.createContainer(Adapter.class,
> resourceConfig, wa);
> if (c != null) {
> return new MyType(c, application);
> }
> }
> }
> }
>
> Or just fork the grizzly container code directly.
>
> We could modify the containers so that they can be cast to a special
> interface to get access to the WebApplication?
>
How about just adding a new create method to GrizzlyWebContainerFactory:

    public SelectorThread create(String u, WebApplication a);

? That way, I could supply a preconfigured and initialized
WebApplication (which therefore already knew about the
GuiceComponentProviderFactory instance wrapping the Guice injector I
want to use).

> Paul.
Craig