spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

PortInUseException is not thrown if system language is not english

Open mhalbritter opened this issue 2 years ago • 4 comments

System language: german

The test Jetty10ServletWebServerFactoryTests#portClashOfPrimaryConnectorResultsInPortInUseException only works if system language is set to english (export LANG=en). But this should be a problem with production code, too.

The code in org.springframework.boot.web.server.PortInUseException#ifPortBindingException checks if the error message contains the words "in use", which is not the case on non-english systems. On a german system the message is "java.net.BindException: Die Adresse wird bereits verwendet" for example.

One can workaround by setting LANG=en java -jar ... when starting the application, then the error message will be english and PortInUseException is thrown.

mhalbritter avatar Feb 21 '22 10:02 mhalbritter

@mhalbritter I have checkout out the 2.5.x branch and I cannot see the portClashOfPrimaryConnectorResultsInPortInUseException test method in the org.springframework.boot.web.embedded.jetty.Jetty10ServletWebServerFactoryTests class.

viktorardelean avatar Mar 06 '22 18:03 viktorardelean

It is inherited from a super-class: https://github.com/spring-projects/spring-boot/blob/1872af056ec059db2316db40ef19e2c1801af208/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java#L916

wilkinsona avatar Mar 06 '22 19:03 wilkinsona

@wilkinsona Thanks for pointing it out! The problem here is that BindException contains just the error message - which is different for every language. Do you have any thoughts on what would be a good fix for this? Should we just remove the if condition: if (bindException.getMessage().toLowerCase().contains("in use")) and accept all BindExceptions in the ifPortBindingException method?

viktorardelean avatar Mar 07 '22 08:03 viktorardelean

The error message comes from the operating system, and depends on the LANG environment variable. We will have to find a better way to determine if there's a port clash going on than parsing the (localized) message. How we do that, I don't know at the moment.

mhalbritter avatar Mar 07 '22 09:03 mhalbritter

Can we try based on the OS type -- lsof, netstat use for this? using ProcessBuilder

somayaj avatar Feb 20 '24 21:02 somayaj

I don't think that's worth it.

mhalbritter avatar Feb 21 '24 08:02 mhalbritter

Well then reading the OS error codes, 98 (EADDRINUSE) or 10048 (WSAEADDRINUSE) ..somewhere in the error stack would do it?

somayaj avatar Feb 21 '24 13:02 somayaj

As far as I know, those error codes do not appear anywhere in the stack trace of the BindException. If you have evidence to the contrary, please do share it.

wilkinsona avatar Feb 21 '24 14:02 wilkinsona

try {
	serverSocket.setReuseAddress(false);
	serverSocket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), 8080), 1);
	serverSocket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), 8080), 1);
} catch (SocketException be) {
	if(serverSocket.isBound()) { // this check here should do it. 
		throw new BindException(be.getMessage());
	}
}

somayaj avatar Feb 21 '24 17:02 somayaj

The code that's trying to bind the socket isn't ours, it's part of the web server that we embed and, therefore, we cannot change it. All that we have available for analysis is the BindException that's thrown by the JDK.

wilkinsona avatar Feb 21 '24 18:02 wilkinsona

Well then we can translate the message/exception based on the lang/locale to en-US and then check for the port in use str?

somayaj avatar Feb 25 '24 22:02 somayaj

Well then we can translate the message/exception based on the lang/locale to en-US and then check for the port in use str?

Any word here?

somayaj avatar Mar 05 '24 20:03 somayaj

@somayaj I'm not sure that translating the message into every possible language is going to be feasible.

philwebb avatar Mar 06 '24 00:03 philwebb

I don't think this one is fixable.

mhalbritter avatar Apr 22 '24 11:04 mhalbritter