You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Christopher Dodunski <Ch...@christopher.net.nz> on 2019/04/17 21:58:27 UTC

Using custom Configurator with WebSockets

Hello,

Just a quick question with regard to extending
ServerEndpointConfig.Configurator to override Tomcat's default action of
instantiating the POJO class annotated with @ServerEndpoint on receiving a
WebSocket request.  My reason for doing this is that my endpoint class
depends on IoC dependency injection, and therefore needs to be got from
the registry to have its dependencies in place.

My Configurator method:


    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws
InstantiationException {
        return
endpointClass.cast(RegistryProxy.getService(HarbourServerEndpoint.class));
    }


The @ServerEndpoint annotation is placed on on my
HarbourServerEndpointImpl POJO class, not the interface that it
implements.  Based on the below runtime catalina.out error message the
problem appears to be that the registry is returning HarbourServerEndpoint
whereas Tomcat is expecting an instance of HarbourServerEndpointImpl?

I'm hoping someone can please explain what is going wrong with my custom
Configurator.


15-Apr-2019 12:45:28.488 SEVERE [http-nio-8080-exec-915]
org.apache.coyote.AbstractProtocol$ConnectionHandler.process Error reading
request, ignored
 java.lang.ClassCastException: Cannot cast
$HarbourServerEndpoint_39c9cc24eb8b2a to
com.optomus.harbour.services.HarbourServerEndpointImpl
        at java.lang.Class.cast(Class.java:3369)
        at
com.optomus.harbour.services.HarbourServerEndpointConfigurator.getEndpointInstance(HarbourServerEndpointConfigurator.java:17)
        at
org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:44)
        at
org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:133)
        at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:846)
        at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
        at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)


Finally, with no casting at all, the compiler gives the error:

    Error:(17, 40) java: incompatible types: inference variable T has
incompatible bounds
        equality constraints:
com.optomus.harbour.services.HarbourServerEndpoint
        upper bounds: T,java.lang.Object


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Using custom Configurator with WebSockets

Posted by Mark Thomas <ma...@apache.org>.
On 17/04/2019 22:58, Christopher Dodunski wrote:
> Hello,
> 
> Just a quick question with regard to extending
> ServerEndpointConfig.Configurator to override Tomcat's default action of
> instantiating the POJO class annotated with @ServerEndpoint on receiving a
> WebSocket request.  My reason for doing this is that my endpoint class
> depends on IoC dependency injection, and therefore needs to be got from
> the registry to have its dependencies in place.
> 
> My Configurator method:
> 
> 
>     @Override
>     public <T> T getEndpointInstance(Class<T> endpointClass) throws
> InstantiationException {
>         return
> endpointClass.cast(RegistryProxy.getService(HarbourServerEndpoint.class));
>     }
> 
> 
> The @ServerEndpoint annotation is placed on on my
> HarbourServerEndpointImpl POJO class, not the interface that it
> implements.  Based on the below runtime catalina.out error message the
> problem appears to be that the registry is returning HarbourServerEndpoint
> whereas Tomcat is expecting an instance of HarbourServerEndpointImpl?
> 
> I'm hoping someone can please explain what is going wrong with my custom
> Configurator.

The custom Configurator looks fine. The problem is with trying to do
this with a POJO endpoint. There is an underlying assumption that - for
a POJO endpoint - the endpoints will will instances of the POJO class.
This doesn't seem to hold in your case so hence it breaks.

The WebSocket spec explicitly states that WebSocket annotations do not
follow Java inheritance so moving the annotation to the interface is not
an option.

I think you are going to have to build your ServerEndpointConfig
programmatically so you can specify the correct endpoint class.

Mark


> 
> 
> 15-Apr-2019 12:45:28.488 SEVERE [http-nio-8080-exec-915]
> org.apache.coyote.AbstractProtocol$ConnectionHandler.process Error reading
> request, ignored
>  java.lang.ClassCastException: Cannot cast
> $HarbourServerEndpoint_39c9cc24eb8b2a to
> com.optomus.harbour.services.HarbourServerEndpointImpl
>         at java.lang.Class.cast(Class.java:3369)
>         at
> com.optomus.harbour.services.HarbourServerEndpointConfigurator.getEndpointInstance(HarbourServerEndpointConfigurator.java:17)
>         at
> org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:44)
>         at
> org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:133)
>         at
> org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:846)
>         at
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
>         at
> org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
>         at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
>         at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
>         at
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
>         at java.lang.Thread.run(Thread.java:748)
> 
> 
> Finally, with no casting at all, the compiler gives the error:
> 
>     Error:(17, 40) java: incompatible types: inference variable T has
> incompatible bounds
>         equality constraints:
> com.optomus.harbour.services.HarbourServerEndpoint
>         upper bounds: T,java.lang.Object
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org