-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Running as deployed WAR two conflicting endpoints are registered #117
Comments
It seems as if first Tomcat auto-detects the endpoint and later Wicket Spring Boot adds it again: First time WicketServerEndpointConfig is added (very early):
Second time WicketServerEndpointConfig is added (via a future after the Spring application has started up):
|
Running in JAR application mode (which works), I get this trace:
|
Adding
in the context.xml also doesn't help. If I do that, I get an NPE instead:
|
I don't know how to prevent this behaviour. Is there a way to stop Tomcat to auto detect the WicketServerEndpointConfig? Can the check if the WicketServerEndpointConfig is already registered in the WicketServerEndpointConfigRegister? Or should we add a property on the WicketServerEndpointConfigRegister bean to disable it? |
Tomcat scans for implementations of some Java EE classes, like Jetty does the same. That's why the Wicket Quickstart Archetype manually registers the endpoint in One workaround that I imagine for this issue is to test for class existence before executing the logic in WicketServerEndpointConfigRegister. E.g. for Tomcat you can test for any ot the embed specific classes. |
I am thinking of two options
|
Another option might be to check if the URL of the WicketServerEndpointConfigRegister class (or any other sensible reference class) hints at being inside a fat-jar. |
I'll try the following: Spring Boots EmbeddedServletContainerAutoConfiguration class creates the factories for the embedded servlet containers (tomcat, jetty, undertow). A EmbeddedServletContainerFactory bean is created here for the specific servlet container. I could configure the WicketServerEndpointConfigRegister only as a bean if the EmbeddedServletContainerFactory bean is present.... |
The WicketServerEndpointConfigRegister is now only configured if the bean EmbeddedServletContainerFactory exits. @reckart are you able to build the starter project and test it?
|
@MarcGiffing that looked promising but I'm afraid for the case that caused me to report the issue originally, it doesn't work. But I also have good news. First why does it not work: it is probably that Eclipse doesn't seem to care much about Maven scopes. So WebSocketWicketWebInitializerAutoConfiguration still triggers even with your changes when running the application in Eclipse via WTP and the endpoint is registered twice. -- IF the setting "Serve modules without publishing" is set to its default value false. IF "Serve modules without publishing" is set to true, then everything works nicely - with 1.0.9 and also with your recent changes. So the good news is that for the purpose of development, I have a workaround and set "Serve modules without publishing" is set to true (which I prefer anyway). The question is: what happens if an actual WAR is build and deployed in a Tomcat outside Eclipse. That is something I haven't tried yet. So we have these situations:
|
Ok, I also tested with a proper WAR build and deployed into a Tomcat 8.5.14. Both with 1.0.9 and 1.0.10-SNAPSHOT an attempt is made to register a second WebSocket endpoint. So we have 4 configurations in total that do not work - neither with 1.0.9 nor with 1.0.10-SNAPSHOT. I have updated the table above accordingly. |
Maybe it would be an option to add a static lookup table into WicketEndpoint proper where every all endpoints register themselves. That could be used e.g. by Spring Boot Wicket Starter to check if a WicketEndpoint has already been deployed under a given URL and not try it again. Another thing that might work is that Spring Boot Wicket Starter could try making a connection to the WicketEndpoint URL and if that works not try registering a second endpoint - although I don't know if the endpoint actually is already able to accept connections at the time Spring Boot Wicket Starter tries to register the second endpoint. |
I've tried different solutions to detect the embedded mode but without luck.
I don't understand this proposal. There have to be a change in the Wicket libraries? How should the Wicket Spring Boot Starter check the url.
I didn't found a solution to get the endpoints to check the existing first. I don't think that a connection is possible while configuration.
I could also add a property on the bean to disable/enable it but then you have add the configuration in your tomcat. |
The proposal regarding the WicketEndpoint maintaining an internal registry would indeed require a change in Wicket itself, yes. A property sounds like a good idea. IMHO the default should be that it is disabled. If the Spring Boot application is deployed as a runnable JAR, then the property should be set to enable the endpoint registration in the |
No, the default should be that it is enabled. For the need of deploying it as a war in a servlet container like tomcat you have to disable it. You can use the SpringBootServletInitializer to disable it. We need to update the documentation with this hint (#115) @Bean
@ConditionalOnProperty(prefix = "wicket.external.websocket.registerServerEndpoint", value = "enabled", matchIfMissing = true)
public WicketServerEndpointConfigRegister wicketServerEndpointConfigRegister() {
return new WicketServerEndpointConfigRegister();
}
@SpringBootApplication
public class WicketApplication extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder()
.sources(WicketApplication.class)
.run(args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
builder.properties( "wicket.external.websocket.register-server-endpoint.enabled=false" );
return super.configure( builder );
}
} |
It would be nice if there was a constant with the property name that could be used. E.g.
|
I'd suggest to create separate class for that. |
I've added a hint in the Readme down below, Here is also a pull request welcome :) |
Running as deployed WAR both standard and web-socket endpoints are triggered. I get this exception:
It doesn't happen when I run via the embedded Tomcat. Any ideas?
The text was updated successfully, but these errors were encountered: