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 <[email protected]>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 <[email protected]
> >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: [email protected]
> >> For additional commands, e-mail: [email protected]
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>