Affects: 6.0.5
Upgrade my Spring RSocket Sample to 6.0.5, it failed with following exception when running tests.
java.lang.NoSuchFieldError: NETWORK_INTERFACES
at io.netty.resolver.dns.DnsNameResolver.anyInterfaceSupportsIpV6(DnsNameResolver.java:170)
at io.netty.resolver.dns.DnsNameResolver.<clinit>(DnsNameResolver.java:122)
at io.netty.resolver.dns.DnsNameResolverBuilder.<init>(DnsNameResolverBuilder.java:52)
at reactor.netty.transport.NameResolverProvider.newNameResolverGroup(NameResolverProvider.java:501)
at reactor.netty.tcp.TcpResources.getOrCreateDefaultResolver(TcpResources.java:315)
at reactor.netty.tcp.TcpClientConfig.defaultAddressResolverGroup(TcpClientConfig.java:104)
at reactor.netty.transport.ClientTransportConfig.resolverInternal(ClientTransportConfig.java:225)
at reactor.netty.transport.ClientTransport.connect(ClientTransport.java:59)
at reactor.netty.tcp.TcpClient.connect(TcpClient.java:193)
at io.rsocket.transport.netty.client.TcpClientTransport.connect(TcpClientTransport.java:118)
at io.rsocket.core.RSocketConnector.lambda$null$6(RSocketConnector.java:551)
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152)
at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)
at reactor.core.publisher.Mono.subscribe(Mono.java:4470)
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:200)
at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
at io.rsocket.core.DefaultRSocketClient.doSubscribe(DefaultRSocketClient.java:190)
at io.rsocket.core.ResolvingOperator.add(ResolvingOperator.java:378)
at io.rsocket.core.ResolvingOperator.observe(ResolvingOperator.java:105)
at io.rsocket.core.DefaultRSocketClient$FlatMapMain.onNext(DefaultRSocketClient.java:302)
at io.rsocket.core.DefaultRSocketClient$FlatMapMain.onNext(DefaultRSocketClient.java:214)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:224)
at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:293)
at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:474)
at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:156)
at reactor.core.publisher.MonoZip$ZipInner.onSubscribe(MonoZip.java:466)
at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48)
at reactor.core.publisher.MonoZip$ZipCoordinator.request(MonoZip.java:216)
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.request(FluxMap.java:295)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.request(FluxContextWrite.java:136)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.request(FluxContextWrite.java:136)
at io.rsocket.core.DefaultRSocketClient$FlatMapMain.request(DefaultRSocketClient.java:327)
at io.rsocket.core.DefaultRSocketClient$FlattingInner.request(DefaultRSocketClient.java:453)
at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164)
at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSubscribe(DefaultStepVerifierBuilder.java:1161)
at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92)
at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92)
at io.rsocket.core.DefaultRSocketClient$FlatMapMain.onSubscribe(DefaultRSocketClient.java:256)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onSubscribe(FluxContextWrite.java:101)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onSubscribe(FluxContextWrite.java:101)
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onSubscribe(FluxMap.java:194)
at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:125)
at reactor.core.publisher.Mono.subscribe(Mono.java:4485)
at io.rsocket.core.DefaultRSocketClient$RSocketClientFluxOperator.subscribe(DefaultRSocketClient.java:555)
at reactor.core.publisher.Flux.subscribe(Flux.java:8671)
at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.toVerifierAndSubscribe(DefaultStepVerifierBuilder.java:891)
at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:831)
at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:823)
at reactor.test.DefaultStepVerifierBuilder.verifyComplete(DefaultStepVerifierBuilder.java:690)
at com.example.demo.IntegrationTests.testGetAllPosts(IntegrationTests.java:46)
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.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at
Check the complete message from Github Actions, https://github.com/hantsy/spring6-sandbox/actions/runs/4249830087/jobs/7390342006#step:5:984
The application is very simple, just to taste the RSocket client interface feature.
@Configuration
@ComponentScan
@PropertySource(value = "classpath:application.properties", ignoreResourceNotFound = true)
public class Application {
public static void main(String[] args) throws Exception {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
Application.class)) {
var rSocketServer = context.getBean(RSocketServer.class);
rSocketServer.bind(TcpServerTransport.create("localhost", 7000)).block();
}
}
@Bean
RSocketServer rSocketServer(RSocketMessageHandler handler) {
return RSocketServer.create(handler.responder());
}
@Bean
public RSocketStrategies rsocketStrategies() {
return RSocketStrategies.builder()
.encoders(encoders -> encoders.add(new Jackson2CborEncoder()))
.decoders(decoders -> decoders.add(new Jackson2CborDecoder()))
.routeMatcher(new PathPatternRouteMatcher())
.build();
}
}
// Client Config
@Configuration
public class ClientConfig {
@Bean
RSocketRequester rSocketRequester(RSocketStrategies strategies) {
return RSocketRequester.builder()
.rsocketStrategies(strategies)
.tcp("localhost", 7000);
}
@SneakyThrows
@Bean
public PostClientService postClientService(RSocketRequester requester) {
RSocketServiceProxyFactory rSocketServiceProxyFactory =
RSocketServiceProxyFactory.builder(requester)
.blockTimeout(Duration.ofMillis(5000))
.build();
return rSocketServiceProxyFactory.createClient(PostClientService.class);
}
}
public interface PostClientService {
@RSocketExchange("posts.findAll")
public Flux<Post> all();
@RSocketExchange("posts.titleContains")
public Flux<Post> titleContains(@Payload String title);
@RSocketExchange("posts.findById.{id}")
public Mono<Post> get(@DestinationVariable("id") UUID id);
@RSocketExchange("posts.save")
public Mono<UUID> create(@Payload Post post);
@RSocketExchange("posts.update.{id}")
public Mono<Boolean> update(@DestinationVariable("id") UUID id, @Payload Post post);
@RSocketExchange("posts.deleteById.{id}")
public Mono<Boolean> delete(@DestinationVariable("id") UUID id);
}
// Server Config
@Configuration
class ServerConfig {
@Bean
public RSocketMessageHandler rsocketMessageHandler(RSocketStrategies rsocketStrategies) {
RSocketMessageHandler handler = new RSocketMessageHandler();
handler.setRSocketStrategies(rsocketStrategies);
return handler;
}
}
The testing codes that throws the exception.
@SpringJUnitConfig(classes = Application.class)
public class IntegrationTests {
@Value("${rsocket.port:7000}")
int port;
@Autowired
PostClientService client;
@Autowired
RSocketServer rSocketServer;
private Closeable disposableServer;
@BeforeEach
public void setup() {
this.disposableServer = this.rSocketServer
.bindNow(TcpServerTransport.create("localhost", port));
}
@AfterEach
public void teardown() {
this.disposableServer.dispose();
}
@Test
public void testGetAllPosts() throws Exception {
this.client.all()
.as(StepVerifier::create)
.expectNextCount(2)
.verifyComplete();
}
}
Comment From: ClaudioRizzo
I am facing a related / similar issue:
java.lang.NoSuchFieldError: NETWORK_INTERFACES
at io.netty.resolver.dns.DnsNameResolver.anyInterfaceSupportsIpV6(DnsNameResolver.java:170) ~[netty-resolver-dns-4.1.89.Final.jar:4.1.89.Final]
at io.netty.resolver.dns.DnsNameResolver.<clinit>(DnsNameResolver.java:122) ~[netty-resolver-dns-4.1.89.Final.jar:4.1.89.Final]
at io.netty.resolver.dns.DnsNameResolverBuilder.<init>(DnsNameResolverBuilder.java:52) ~[netty-resolver-dns-4.1.89.Final.jar:4.1.89.Final]
at reactor.netty.transport.NameResolverProvider.newNameResolverGroup(NameResolverProvider.java:501) ~[reactor-netty-core-1.1.3.jar:1.1.3]
at reactor.netty.tcp.TcpResources.getOrCreateDefaultResolver(TcpResources.java:315) ~[reactor-netty-core-1.1.3.jar:1.1.3]
at reactor.netty.http.HttpResources.getOrCreateDefaultResolver(HttpResources.java:162) ~[reactor-netty-http-1.1.3.jar:1.1.3]
at reactor.netty.http.client.HttpClientConfig.defaultAddressResolverGroup(HttpClientConfig.java:396) ~[reactor-netty-http-1.1.3.jar:1.1.3]
at reactor.netty.transport.ClientTransportConfig.resolverInternal(ClientTransportConfig.java:225) ~[reactor-netty-core-1.1.3.jar:1.1.3]
at reactor.netty.http.client.HttpClientConfig.resolverInternal(HttpClientConfig.java:450) ~[reactor-netty-http-1.1.3.jar:1.1.3]
at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.lambda$subscribe$0(HttpClientConnect.java:269) ~[reactor-netty-http-1.1.3.jar:1.1.3]
at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:58) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.FluxRetryWhen.subscribe(FluxRetryWhen.java:77) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoRetryWhen.subscribeOrReturn(MonoRetryWhen.java:46) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:276) ~[reactor-netty-http-1.1.3.jar:1.1.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoCacheTime.subscribeOrReturn(MonoCacheTime.java:143) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.Mono.subscribe(Mono.java:4470) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:126) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) ~[reactor-core-3.5.3.jar:3.5.3]
at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) ~[reactor-core-3.5.3.jar:3.5.3]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Comment From: sbrannen
Upgrade my Spring RSocket Sample to 6.0.5, it failed with following exception when running tests.
What version of Spring Framework did you upgrade from?
In any case, it sounds like an incompatibility with the version of one or more Netty artifacts -- and thus perhaps not directly related to Spring.
Have you verified that your various Netty artifacts are compatible?
Comment From: hantsy
What version of Spring Framework did you upgrade from?
Upgraded 6.0.4 to 6.0.5, and failed with the above exception.
Have you verified that your various Netty artifacts are compatible?
Managed by reactor-bom, the version is:
<reactor.version>2022.0.3</reactor.version>
Reactor Netty deps added:
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
</dependency>
Check the sample project here.
https://github.com/hantsy/spring6-sandbox/blob/master/declarative-rsocket-client
Comment From: rstoyanchev
The field was added in Netty 4.1.87 with https://github.com/netty/netty/commit/8da8f2709ed001882184d2367580739c0cc89ad4, and the class expecting it is another Netty class, which points to a mix of versions for Netty modules.
Netty is an optional dependency in the Spring Framework, and therefore this is completely unrelated to the switch from 6.0.4 to 6.0.5. Instead your pom picked up a newer version of Reactor Netty since the last time you ran the sample, because in the pom the version is not specified, and therefore set to get the latest.
$ mvn dependency:tree
...
[INFO] +- io.rsocket:rsocket-core:jar:1.1.3:compile
[INFO] | \- io.netty:netty-buffer:jar:4.1.81.Final:compile
[INFO] | \- io.netty:netty-common:jar:4.1.81.Final:compile
[INFO] +- io.rsocket:rsocket-transport-netty:jar:1.1.3:compile
[INFO] | +- io.projectreactor.netty:reactor-netty-core:jar:1.1.3:compile
[INFO] | | + ...
[INFO] | | +- io.netty:netty-resolver-dns:jar:4.1.89.Final:compile
...
[INFO] +- io.projectreactor.netty:reactor-netty:jar:1.1.3:compile
[INFO] | \- io.projectreactor.netty.incubator:reactor-netty-incubator-quic:jar:0.1.3:runtime
[INFO] | \- io.netty.incubator:netty-incubator-codec-native-quic:jar:linux-x86_64:0.0.36.Final:runtime
[INFO] | \- io.netty.incubator:netty-incubator-codec-classes-quic:jar:0.0.36.Final:runtime
[INFO] | \- commons-codec:commons-codec:jar:1.15:runtime
...
You can see the mix of netty-common 4.1.81 and netty-resolver-dns 4.1.89.
Either you need to set to a lower Reactor Netty version explicitly, probably 1.1.1, or exclude reactor-netty-buffer from your RScocket dependencies. Or use a new version of RSocket Java compiled against Netty 4.1.87 or higher, and that does not exist at the moment. There is an issue for it https://github.com/rsocket/rsocket-java/issues/1082.