We didn't change anything in our code or configuration, other than upgrading versions.
We can run the service locally, and can run the tests individually. But when we try to run the tests together, we get the port error.
We were already on Spring 6.1.0 and Spring Boot 3.1.5, so this should have been a small upgrade.
We're using the latest version of JUnit, and are not running the tests in parallel.
The tests fail with the port error whether virtual threads are enabled or disabled.
Is there some new cleanup/finalization we need to add? We looked at the release notes for both Spring and Spring Boot and didn't see anything relevant.
Comment From: yanivnahoum
Seeing the same thing. Not sure if in @jimshowalter 's configuration 8090 is the value of management.server.port, but in my case, when I assign a value to management.server.port, a few @SpringBootTests start failing with "Port xxxx is already in use", where xxxx is the value of management.server.port
Comment From: wilkinsona
I'm not aware of anything that would have changed the behavior here. Perhaps https://github.com/spring-projects/spring-boot/issues/38502, but that's little more than a guess at this point.
If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.
Comment From: jimshowalter
8090 is the management.server.port we use in tests. If we change management.server.port to some other port, we get the same error.
Comment From: jimshowalter
You're asking us to try to cut a huge pile of intellectual property down to a reproducible test case, but we know something in the latest Spring or Spring Boot causes this, and you're way more famliar with that codebase than we are.
This will block many developers from using virtual threads. Can you please fix this problem?
Comment From: wilkinsona
we know something in the latest Spring or Spring Boot causes this, and you're way more famliar with that codebase than we are
We know that a combination of something in your codebase and something in the latest Spring or Spring Boot causes this. We know nothing about your codebase and you know something about ours. It's very helpful if someone who's familiar with both sides of the problem spends some time creating a minimal reproducer.
Can you please fix this problem?
We were not refusing to fix it, far from it, just looking for some assistance in addressing the problem that you've reported.
I have now managed to reproduce the problem and, as guessed above, #38502 is the cause unfortunately. A (far from ideal) partial workaround is to use @DirtiesContext to prevent caching of test contexts.
Comment From: jimshowalter
That was fast!
Do you have a sense for when the next release will be published?
Comment From: jimshowalter
"We know that a combination of something in your codebase and something in the latest Spring or Spring Boot causes this. We know nothing about your codebase and you know something about ours. It's very helpful if someone who's familiar with both sides of the problem spends some time creating a minimal reproducer."
That's a very fair point. Unfortunately, our codebase is massive, and every time we try to reduce it to a reproducible example, we fail.
Comment From: jimshowalter
There may still be a problem, because we copied the previous version of https://github.com/spring-projects/spring-boot/blob/ed9169501efb278942f7e6016cc235e1979f38c0/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java into our service, and our tests still failed.
Comment From: jimshowalter
We can offer a joint debugging session in Zoom or similar.
Comment From: mr-hamburg
Good morning from Hamburg! Our RenovateBot tried to update the version of the artefact "spring-boot-starter-parent" from version 3.1.5 to 3.2.0 on Friday morning, whereupon all build pipelines in all our projects failed. We have not made any changes to the code that would cause this error. Our management port is 8900 and the error message looks like this:
Caused by: org.springframework.boot.web.server.PortInUseException: Port 8900 is already in use
I understand that it is valuable to have a reproducible test, how does this work for you?
@SpringBootTest
@ActiveProfiles("test")
class ApplicationTests {
@Autowired
private ApplicationContext applicationContext;
@Test
void contextLoads() {
assertThat(applicationContext).isNotNull();
}
}
Running this test individually works, there is no error. However, if I run all tests of the project, I get this error. It seems to me that the test framework does not work cleanly enough when cleaning up previous test artefacts, so that residues are left behind which can lead to the management port still being in use.
I am very interested in finding a solution and would like to plead for this ticket to be categorised as high as possible so that the process is processed with the greatest urgency.
Comment From: wilkinsona
I understand that it is valuable to have a reproducible test, how does this work for you?
I doesn't help, I'm afraid.
Running this test individually works, there is no error. However, if I run all tests of the project, I get this error.
You've only provided us with this one test so we have no insight into what other tests are needed to trigger the problem.
I am very interested in finding a solution and would like to plead for this ticket to be categorised as high as possible so that the process is processed with the greatest urgency.
Exerting this kind of pressure doesn't really help anyone. A fix that's made without pressure is much more likely to be successful than one that's done under pressure and in a rush.
If Spring Boot 3.2.0 doesn't work for you, Spring Boot 3.1.x is still available and fully supported.
Comment From: wilkinsona
There may still be a problem
Thanks for trying that, @jimshowalter. Can you please run your tests with a breakpoint in ChildManagementContextInitializer.createManagementContext() and share the stack trace of when that method is called.
Comment From: mr-hamburg
You've only provided us with this one test so we have no insight into what other tests are needed to trigger the problem.
This is absolutely correct and at the same time I will not post any further tests on the internet that reveal internal company specifics, thank you for your understanding. This one test, executed separately, works fine, but it fails in the project as a whole.
Exerting this kind of pressure doesn't really help anyone. A fix that's made without pressure is much more likely to be successful than one that's done under pressure and in a rush.
At this point I apologise. I didn't mean to exert any pressure, but rather to show my willingness to help. I'm sorry that I expressed myself incorrectly. Of course you are right, a quick solution can never be the right one. If there's anything I can do that doesn't violate my company rules that will help, please let me know.
If Spring Boot 3.2.0 doesn't work for you, Spring Boot 3.1.x is still available and fully supported.
That's good, because we don't always have to adapt the latest version straight away. We will get by with it and are in no rush. Thank you for your work!
Comment From: soer84
i took the liberty and created a reproducer for a case we're currently facing. The tests in the attached zip file work with spring boot 3.1.5 but fail on 3.2.0. - It might be a different root cause but the result seems to be same - a blocked Port.
In my example I just add a new http connector with a fixed port. When running each test on its own they work. But if they're executed in a row i.e. by a mvn verify the second tests fails on initialization stating that the configured connector failed to start.
Maven doesn't print the reason too clearly unfortunately but a little closer investigation inside a IDE reveals the java.net.BindException: Address already in use: bind exception.
In this example also the "@DirtiesContext" doesn't help. It seems to me as if the Spring / ApplicationContext is cleaned up and the server is rebooted but the old instance of the server hasn't shut down yet or isn't shutting down at all.
Comment From: wilkinsona
Thanks, @soer84. That appears to be an unrelated problem as you are not used Actuator. Please open a new issue so that your problem can be investigated separately.
Comment From: yanivnahoum
@wilkinsona Here we go: https://github.com/yanivnahoum/spring-boot-examples/tree/port-in-use
Please clone and check out the branch above (port-in-use).
Run ./mvnw test to see the error.
To reproduce it, I did 2 things:
1. Specified a value for management.server.port
2. Added 2 @SpringBootTests, one of which adds a property to the context (in order to force Spring not to re-use the existing one).
Let me know if this helps!
Comment From: jimshowalter
@wilkinsona, https://github.com/wilkinsona/spring-boot/commit/9503e450e84e443d9e29590cab3f6f51df3fb8db fixes the problem originally reported in this issue!
Comment From: jimshowalter
How long does it take to publish a new Spring Boot bug-fix version?
Comment From: jimshowalter
@yanivnahoum, if you copy https://github.com/wilkinsona/spring-boot/blob/9503e450e84e443d9e29590cab3f6f51df3fb8db/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java into https://github.com/yanivnahoum/spring-boot-examples/tree/port-in-use does it fix the problem?
Comment From: yanivnahoum
@jimshowalter what do you mean copy it in? This class is coming from org.springframework.boot:spring-boot-actuator-autoconfigure:3.2.0 . How can I patch it?
Comment From: jimshowalter
Create a package in your local with the same name as the package in the actuator code, copy the fixed source file into it. It's called class shadowing. Your local classes load ahead of dependencies, so you basically substitute the .class file at load time for what would have been on your classpath from the actuator jar. Decent article: https://medium.com/@akhaku/java-class-shadowing-and-shading-9439b0eacb13. (Doesn't work for JRE classes.)
Comment From: yanivnahoum
I was afraid you'd say that :-) Anyway, I'll leave it to the master @wilkinsona to check it, since I won't be upgrading until a fix is out anyway. Thanks!
Comment From: jimshowalter
I meant try it in your repo where you reproduced the problem.
Comment From: benno-sc
I tried the fix originally by @wilkinsona, linked by @jimshowalter and can confirm that it fixed the issue in my project.
Comment From: jimshowalter
Excellent!
Comment From: wilkinsona
How long does it take to publish a new Spring Boot bug-fix version?
Our release plans are, as ever, available on the milestone page. Spring Boot 3.2.1 is scheduled for December 21.
Comment From: jimshowalter
3.2.1 doesn't mention the fix for this issue, which is why I asked.
Comment From: larsgrefer
I've stumbled upon the same issue. Our tests were working fine in 3.2.0-RC2 but are broken with 3.2.0
This minimal project can be used to reproduce the problem: https://github.com/larsgrefer/actuator-test-demo
Comment From: jimshowalter
@larsgrefer if you shadow the fix in actuator-test-demo, does it work?: https://github.com/wilkinsona/spring-boot/blob/9503e450e84e443d9e29590cab3f6f51df3fb8db/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java
Comment From: pcornelissen
As workaround you can try to set the actuator port to the same port as the regular port. This "fixed" the problem for me.
Comment From: juliojgd
As workaround you can try to set the actuator port to the same port as the regular port. This "fixed" the problem for me.
This does not work as workaround, because changing requisites can'be called "workaround" IMHO
Comment From: pcornelissen
Well in my running service I prefer the actuator on a dedicated port, in my tests it usually doesn't matter, so I change an aspect, that is of no difference to my tests, while solving a real problem withi the tests. So if your tests don't break when actuator is not on a dedicated port, feel free to set both to the same value for tests to have green tests again. If it is a problem for your tests, then you might want to stay on 3.1.x until 3.2.1 is out.
Comment From: ivan-vlasenko
One thing that you could try to do, that actually worked for me, it's to override a management port in certain @SpringBootTest via properties to random one "management.server.port=0". In that case you could avoid unwanted changes in your production code.
Comment From: priyanka2277
I am using springboot framework .Once i had used port 8080 and save the data in the database ,next time i am running the program the port already used error comes how to use only one port permanently without changing the port multiple times
Comment From: pcornelissen
I think you are talking about a different problem. This issue concerns a service that has a lot of tests and during these tests the service code under test ran into the port in use when all tests were ran. If you want to start the service itself and the port is taken, just check what runs on that port. Assumably you have another service or an older version of this service running on port 8080. The ports are not blocked forever, just because you once starten something that listens on a port. Depending on your operating system, you have different ways to figure out what blocks a port.
For Windows, there are tools you can download for that. For Mac you can for example use brew and instakk "killport" which kills the application that blocks a port doing "killport 8080" frees up that port. On linux you could "netstat -tulpen|grep 8080" this would return the processes that listen on port 8080 and one of the first coliums is the PID and you can kill that pid or do a "ps aux|grep ..." to find out about the process