Skip to content
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

Why does not tomcat throw an exception when server.start failed with a socket binding error. #3236

Closed
chickenlj opened this issue Jan 15, 2019 · 4 comments · Fixed by #3589
Closed
Labels
type/bug Bugs to being fixed
Milestone

Comments

@chickenlj
Copy link
Contributor

Why does not tomcat throw an exception when server.start failed with a socket binding error.

https://github.com/apache/incubator-dubbo/blob/master/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/tomcat/TomcatHttpServer.java#L71

I do see the exception stack printed on the Console, whereas no exception was thrown in here:

try {
            tomcat.start();
        } catch (LifecycleException e) {
            throw new IllegalStateException("Failed to start tomcat server at " + url.getAddress(), e);
        } catch (Exception ee) {
            throw new IllegalStateException(e);
        }

This behavior will cause a tomcat based HTTP service being registered unexpectedly to the Registry even after the binding has failed.

@Override
    public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
         ... ...
        // socket binding exception extected
        final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker, providerUrl);
        ... ... 
        // url to registry
        final Registry registry = getRegistry(originInvoker);
        register(registryUrl, registeredProviderUrl);
         
        return new DestroyableExporter<>(exporter);
    }
@ralf0131
Copy link
Contributor

Can you provide the error stack trace?

@chickenlj
Copy link
Contributor Author

try {
                    connector.init();
                } catch (Exception var9) {
                    String message = sm.getString("standardService.connector.initFailed", new Object[]{connector});
                    log.error(message, var9);
                    if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
                        throw new LifecycleException(message);
                    }
                }

Turns out that there's a if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) check that will decide whether tomcat will throw the exception out. By default, the return value would be false because we haven't set the org.apache.catalina.startup.EXIT_ON_INIT_FAILURE value, so it just skipped the throw action.

@chickenlj
Copy link
Contributor Author

Here's the stack trace:

INFO: Initializing ProtocolHandler ["http-bio-8080"]
Jan 15, 2019 5:29:14 PM org.apache.coyote.AbstractProtocol init
SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-8080"]
java.net.BindException: Address already in use (Bind failed) <null>:8080
	at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:413)
	at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:728)
	at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:452)
	at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119)
	at org.apache.catalina.connector.Connector.initInternal(Connector.java:978)
	at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
	at org.apache.catalina.core.StandardService.initInternal(StandardService.java:560)
	at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
	at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:840)
	at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:135)
	at org.apache.catalina.startup.Tomcat.start(Tomcat.java:372)
	at org.apache.dubbo.remoting.http.tomcat.TomcatHttpServer.<init>(TomcatHttpServer.java:71)
	at org.apache.dubbo.remoting.http.tomcat.TomcatHttpBinder.bind(TomcatHttpBinder.java:28)
	at org.apache.dubbo.remoting.http.HttpBinder$Adaptive.bind(HttpBinder$Adaptive.java)
	at org.apache.dubbo.rpc.protocol.http.HttpProtocol.doExport(HttpProtocol.java:80)
	at org.apache.dubbo.rpc.protocol.AbstractProxyProtocol.export(AbstractProxyProtocol.java:71)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:108)
	at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:57)
	at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:63)
	at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java)
	at org.apache.dubbo.registry.integration.RegistryProtocol.doLocalExport(RegistryProtocol.java:221)
	at org.apache.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:181)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:106)
	at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:55)
	at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:61)
	at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java)
	at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:553)
	at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:402)
	at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:363)
	at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:345)
	at org.apache.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:104)
	at org.apache.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:55)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
	at org.apache.dubbo.samples.http.HttpProvider.main(HttpProvider.java:31)
Caused by: java.net.BindException: Address already in use (Bind failed)
	at java.net.PlainSocketImpl.socketBind(Native Method)
	at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
	at java.net.ServerSocket.bind(ServerSocket.java:375)
	at java.net.ServerSocket.<init>(ServerSocket.java:237)
	at java.net.ServerSocket.<init>(ServerSocket.java:181)
	at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:49)
	at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:400)
	... 42 more

@ralf0131
Copy link
Contributor

Yes, you need to set org.apache.catalina.startup.EXIT_ON_INIT_FAILURE to true in order to let Tomcat to fail during initialization.

@ralf0131 ralf0131 added the type/bug Bugs to being fixed label Jan 15, 2019
@ralf0131 ralf0131 added this to the 2.7.1 milestone Jan 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/bug Bugs to being fixed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants