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

Incompatibility with Spring 6 - ClassNotFoundException: org.springframework.util.SocketUtils #826

Open
chaitanya87 opened this issue Jan 19, 2023 · 10 comments
Labels
feedback required Information are missing or feedback for suggestions is requested incompatibility Incompatibilities between components or versions

Comments

@chaitanya87
Copy link

chaitanya87 commented Jan 19, 2023

SocketUtils class has been removed from Spring 6 (spring-projects/spring-framework#28054) which is still used in net.devh.boot.grpc.server.config.GrpcServerProperties class.

Is there any plan to replace SocketUtils?

Originally posted by @chaitanya87 in https://github.com/yidongnan/grpc-spring-boot-starter/issues/778#issuecomment-1396811385

@ST-DDT
Copy link
Collaborator

ST-DDT commented Jan 19, 2023

Can you give me the full stacktrace please?

Does this error only occur when port = 0 or always?

@ST-DDT ST-DDT added feedback required Information are missing or feedback for suggestions is requested incompatibility Incompatibilities between components or versions labels Jan 19, 2023
@chaitanya87
Copy link
Author

It is happening for port = 0 used in Spring Tests where we want random port to be used during test execution.
@SpringBootTest(properties = "grpc.server.port=0")

Can we replace SocketUtils with TestSocketUtils, refer spring-projects/spring-framework#29132.

@chaitanya87
Copy link
Author

Caused by: java.lang.NoClassDefFoundError: org/springframework/util/SocketUtils
	at net.devh.boot.grpc.server.config.GrpcServerProperties.getPort(GrpcServerProperties.java:429)
	at net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration.grpcInfoContributor(GrpcServerMetricAutoConfiguration.java:82)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139)
	... 147 more
Caused by: java.lang.ClassNotFoundException: org.springframework.util.SocketUtils
	... 154 more

@dsyer
Copy link
Contributor

dsyer commented Jan 19, 2023

TestSocketUtils isn't really suitable for use outside a test. It would be better if GrpcServerProperties just returned 0 if it was set to 0, and then you wouldn't need the socket utils (the OS would find an ephemeral port for you). We would need to expose the port of the running server somewhere still (e.g. in GrpcServerLifecycle) and track down all the places it is needed.

Also relevant for #759

@dsyer
Copy link
Contributor

dsyer commented Jan 20, 2023

The good news is that if you don't use grpc.server.port=0 then everything works, at least in a vanilla server sample. That gives us some wiggle room. Maybe it would be good to have a couple of Spring Boot 3 samples in the project? I don't know the best way to do that since I am a Gradle dunce (the existing samples inherit configuration from the top level so they don't stand alone), but if anyone is able to help with setting that up I'm open to suggestion. Here's a branch with a standalone sample that works: https://github.com/dsyer/grpc-spring-boot-starter/tree/springboot3. Probably there's a better way to get the dependencies.

@dsyer
Copy link
Contributor

dsyer commented Jan 20, 2023

What if we just copy the code from SocketUtils into this project and make it package private? It's not the best long term solution, but it will get us to Spring Boot 3 with the least amount of hassle.

@stillya
Copy link

stillya commented Apr 2, 2023

Any updates? I'm eager to help, but I'm not sure which solution would be best. On one hand, we could let the operating system choose the ephemeral port for us, but on the other hand, it's quite useful, especially during testing, when I know the port before the server is started. Therefore, I believe that @dsyer's proposed approach is the best.
P.S. I can assist in creating a standalone Spring Boot 3 example based on @dsyer's solution, but with improvements such as removing the io.spring.dependency-management plugin and enhancing the dependency declaration.

@ST-DDT
Copy link
Collaborator

ST-DDT commented Apr 2, 2023

In combination with https://github.com/yidongnan/grpc-spring-boot-starter/issues/873 it looks like we have to change the way we assign the port.
E.g. start the server with a random port first and then use that instead of the other way round.

@dsyer
Copy link
Contributor

dsyer commented Apr 3, 2023

Starting the server first would mean a behaviour and/or API change - the least disruptive way would be to not try to return the actual physical port from GrpcServerProperties (getPort() would return 0), but that will break anyone that relies on GrpcServerProperties to inspect the port. That's why I proposed an intermediate step of copying SocketUtils. But if you are OK with a behaviour change or you want to go straight to a major release, I agree there is no need.

#873 is essentially the main reason Spring withdrew its SocketUtils.

@yidongnan
Copy link
Collaborator

I'd prefer to copy the SocketUtils file first so that there are no compatibility issues at the moment, and then consider how to fix the issue in #873 later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feedback required Information are missing or feedback for suggestions is requested incompatibility Incompatibilities between components or versions
Projects
None yet
Development

No branches or pull requests

5 participants