Nick,

Thank you once again. In a servlet injector can be accessed through
getServletContext.getAttribute("Injector")

As you said, I had to implement static method that returns instance of
injector and use it in my EndpointConfiguration to instantiate
ServerEndpoint. This is what I have done:

// The listener installs Guice modules through GuiceServletConfigFactory

public class GuiceServletConfig extends GuiceServletContextListener {
  @Override    protected Injector getInjector() {        return
GuiceServletConfigFactory.getInjector();    }}


// GuiceServletConfigFactory has static method that returns instance of
injector

public class GuiceServletConfigFactory {    private static final
Injector injector = Guice.createInjector(            new
ServerModule(), new DispatchServletModule());    public static
Injector getInjector() {        return injector;    }}


// ServerEndpoint uses WsEndpointConfiguration to instantiate it

@ServerEndpoint(value = "/wsendpoint", configurator =
WsEndpointConfigurator.class, decoders =
JsonRPCRequestDecoder.class)public class WsEndpoint { ... }


// WsEndpointConfiguration can access injector and use it to instantiate
ServerEndpoint class

public class WsEndpointConfigurator extends Configurator {
@Override    public <T> T getEndpointInstance(Class<T> endpointClass)
          throws InstantiationException {        return (T)
GuiceServletConfigFactory.getInjector().getInstance(
endpointClass);    }}


The full source code: https://bitbucket.org/markosankovic/wsgwtp

On 7 November 2013 16:44, Nick Williams <nicho...@nicholaswilliams.net>wrote:

>
> On Nov 6, 2013, at 4:24 PM, Marko Sanković wrote:
>
> > Nick, thanks for your quick response.
> >
> > Unfortunately, specifying javax.websocket.server.ServerEndpointConfig.
> > Configurator is still not enough. This is what I have tried so far:
> >
> > @ServerEndpoint(value = "/wsendpoint", configurator =
> > WsEndpointConfigurator.class)
> > public class WsEndpoint {
> >    @Inject
> >    InjectedSimpleBean injectedSimpleBean;
> >    ...
> > }
> >
> > and the WsEndpointConfigurator.java:
> >
> > public class WsEndpointConfigurator extends Configurator {
> >
> >    @Inject
> >    Injector injector;
> >
> >    @Override
> >    public <T> T getEndpointInstance(Class<T> endpointClass)
> >            throws InstantiationException {
> >        return (T) injector.getInstance(endpointClass);
> >    }
> > }
> >
> > As expected attribute injector is null. To my understanding configurator
> > has to be instantiated through guice, same for the class that
> instantiates
> > configurator (ServerEndpointConfig). How can I do that?
> >
> > Tyrus has the sample of what I really need:
> > https://tyrus.java.net/documentation/1.3/user-guide.html#d0e1075. In my
> > case, I have to achieve that with Google Guice and Tomcat 7.0.47.
> >
> > Thanks
>
> Marko,
>
> Guice is not going to be able to instantiate your WsEndpointConfigurator,
> so you cannot have your Injector injected. The same problem exists with
> Spring's SpringConfigurator. The container, not the framework, instantiates
> it. The solution is to call some static method to "look up" the injector.
> For SpringConfigurator, that means calling
> ContextLoader.getCurrentWebApplicationContext() and using the returned
> ApplicationContext to instantiate the endpoint. I do not know what the
> equivalent is in Guice because I have never used Guice before. However, I'm
> sure Guice has something similar. It wouldn't be very flexible if it didn't.
>
> Nick
>
> >
> > On 6 November 2013 16:23, Nick Williams <nicho...@nicholaswilliams.net
> >wrote:
> >
> >>
> >> On Nov 6, 2013, at 7:55 AM, Marko Sanković wrote:
> >>
> >>> Hi,
> >>>
> >>> For the last couple of hours I've been trying to inject a simple object
> >>> into the class that is @ServerEndpoint annotated.
> >>>
> >>> As stated: Tomcat implements the Java WebSocket 1.0 API defined by
> >> JSR-356.
> >>>
> >>> I'm using Guice as dependency injection framework and Tomcat 7.0.47.
> >>>
> >>> This is how my websocket server endpoint looks like:
> >>>
> >>> ...
> >>> import com.google.inject.Inject;
> >>> ...
> >>> @ServerEndpoint("/wsendpoint")
> >>> public class WsEndpoint {
> >>>
> >>>   @Inject
> >>>   InjectedSimpleBean injectedSimpleBean;
> >>>
> >>>   ...
> >>> }
> >>>
> >>> I can connect to this endpoint, send and receive messages, but
> >>> injectedSimpleBean attribute is null (as expected).
> >>>
> >>> I guess I will have to change the
> >>> way
> >>
> java/org/apache/tomcat/websocket/server/DefaultServerEndpointConfigurator.java
> >>> instantiates endpoint class, the getEndpointInstace method will have to
> >>> call something like:
> >>>
> >>> injector.getInstance(clazz);
> >>>
> >>> but, then again the DefaultServerEndpointConfiguration will also have
> be
> >>> instantiated by the injector.
> >>>
> >>> Any help would be appreciated. Thanks
> >>
> >> Changing the Tomcat-specific class won't be necessary. You can do this
> >> with just the API. In your @ServerEndpoint annotation, you need to
> specify
> >> a different configuration that extends
> >> javax.websocket.server.ServerEndpointConfig.Configurator. Spring
> Framework
> >> has a class [1] that does just this for its DI and other bean
> processing.
> >> You can probably create a class modeled after that.
> >>
> >> Nick
> >>
> >> [1]
> >>
> https://github.com/spring-projects/spring-framework/blob/master/spring-websocket/src/main/java/org/springframework/web/socket/server/endpoint/SpringConfigurator.java?source=cc
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> >> For additional commands, e-mail: users-h...@tomcat.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to