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

UnsupportedOperationException thrown on macos with KQueue in 4.1.54.Final with io.netty.noUnsafe set to true #10813

Closed
henrychv opened this issue Nov 23, 2020 · 5 comments · Fixed by #10814 or #10870
Assignees
Milestone

Comments

@henrychv
Copy link

We updated our spring boot project to version 2.3.6.RELEASE which uses netty 4.1.54.Final and now exceptions like the one below are thrown.

When we override version of netty dependencies to 4.1.53.Final in our project, everything works again. (Works also when noUnsafe set to false or when nio is used instead of kqueue).

Expected behavior

Result is returned from rest api calls.

Actual behavior

Exception is thrown:

Caused by: java.lang.UnsupportedOperationException: null
	at io.netty.buffer.UnpooledDirectByteBuf.memoryAddress(UnpooledDirectByteBuf.java:196) ~[netty-buffer-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.buffer.SwappedByteBuf.memoryAddress(SwappedByteBuf.java:987) ~[netty-buffer-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.unix.IovArray.add(IovArray.java:100) ~[netty-transport-native-unix-common-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.unix.IovArray.processMessage(IovArray.java:223) ~[netty-transport-native-unix-common-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.ChannelOutboundBuffer.forEachFlushedMessage(ChannelOutboundBuffer.java:780) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.kqueue.AbstractKQueueStreamChannel.doWriteMultiple(AbstractKQueueStreamChannel.java:352) ~[netty-transport-native-kqueue-4.1.54.Final-osx-x86_64.jar:4.1.54.Final]
	at io.netty.channel.kqueue.AbstractKQueueStreamChannel.doWrite(AbstractKQueueStreamChannel.java:274) ~[netty-transport-native-kqueue-4.1.54.Final-osx-x86_64.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:941) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.kqueue.AbstractKQueueChannel$AbstractKQueueUnsafe.flush0(AbstractKQueueChannel.java:506) ~[netty-transport-native-kqueue-4.1.54.Final-osx-x86_64.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:905) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1372) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:750) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:742) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:728) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.flush(CombinedChannelDuplexHandler.java:531) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:125) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.CombinedChannelDuplexHandler.flush(CombinedChannelDuplexHandler.java:356) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:750) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:742) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:728) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:127) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:750) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:765) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:808) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1025) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:294) ~[netty-transport-4.1.54.Final.jar:4.1.54.Final]
	at reactor.netty.http.HttpOperations.lambda$send$0(HttpOperations.java:123) ~[reactor-netty-0.9.14.RELEASE.jar:0.9.14.RELEASE]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
    ...

Steps to reproduce

Create Spring Boot project (use version 2.3.6.Release) with added Reactive Web.

In generated pom add dependency:

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-transport-native-kqueue</artifactId>
	<classifier>osx-x86_64</classifier>
</dependency>

When launching add parameter -Dio.netty.noUnsafe=true to jvm.

Minimal yet complete reproducer code (or URL to code)

    @SpringBootApplication
    public class DemoApplication {
        @RestController
        public static class DemoRestController {
            @GetMapping(value = "/all",
                produces = MediaType.APPLICATION_JSON_VALUE)
            public ResponseEntity<List<String>> getAll(@RequestParam int limit) {
                List<String> retval = new ArrayList<>(limit);
                for (int i=0; i<=limit; i++)
                    retval.add("" + i);
        
                return new ResponseEntity<>(retval, HttpStatus.OK);
            }
        }

    	public static void main(String[] args) {
    	    SpringApplication.run(DemoApplication.class, args);
	
    	    WebClient client = WebClient.create("http://localhost:8080");
    	    Mono<ClientResponse> result = client.get()
                .uri("/all?limit=1000")
                .accept(MediaType.APPLICATION_JSON)
                .exchange();
            System.out.println(result.flatMap(res -> res.bodyToMono(String.class)).block());
        }
    }

Netty version

4.1.54.Final

JVM version (e.g. java -version)

openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.7+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.7+10, mixed mode)

OS version (e.g. uname -a)

Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64

@normanmaurer
Copy link
Member

Yes thats a bug... Let me fix it asap.

normanmaurer added a commit that referenced this issue Nov 23, 2020
Motivation:

In some enviroments sun.misc.Unsafe is not present. We should support these as well.

Modifications:

Fallback to JNI if we can't directly access the memoryAddress of the buffer.

Result:

Fixes #10813
@normanmaurer
Copy link
Member

Fixed #10814

@normanmaurer normanmaurer added this to the 4.1.55.Final milestone Nov 23, 2020
normanmaurer added a commit that referenced this issue Nov 23, 2020
Motivation:

In some enviroments sun.misc.Unsafe is not present. We should support these as well.

Modifications:

Fallback to JNI if we can't directly access the memoryAddress of the buffer.

Result:

Fixes #10813
normanmaurer added a commit that referenced this issue Nov 23, 2020
Motivation:

In some enviroments sun.misc.Unsafe is not present. We should support these as well.

Modifications:

Fallback to JNI if we can't directly access the memoryAddress of the buffer.

Result:

Fixes #10813
@henrychv
Copy link
Author

henrychv commented Dec 16, 2020

Unfortunately the reported problem is still there even with 4.1.55. I tried 4.1.55 with 2.3.6 and 2.4.1, still same behaviour:

Caused by: java.lang.UnsupportedOperationException: null
	at io.netty.buffer.UnpooledDirectByteBuf.memoryAddress(UnpooledDirectByteBuf.java:196) ~[netty-buffer-4.1.55.Final.jar:4.1.55.Final]
	at io.netty.buffer.SwappedByteBuf.memoryAddress(SwappedByteBuf.java:987) ~[netty-buffer-4.1.55.Final.jar:4.1.55.Final]
	at io.netty.channel.unix.IovArray.memoryAddress(IovArray.java:215) ~[netty-transport-native-unix-common-4.1.55.Final.jar:4.1.55.Final]
	at io.netty.channel.kqueue.AbstractKQueueStreamChannel.writeBytesMultiple(AbstractKQueueStreamChannel.java:153) ~[netty-transport-native-kqueue-4.1.55.Final-osx-x86_64.jar:4.1.55.Final]
	at io.netty.channel.kqueue.AbstractKQueueStreamChannel.doWriteMultiple(AbstractKQueueStreamChannel.java:356) ~[netty-transport-native-kqueue-4.1.55.Final-osx-x86_64.jar:4.1.55.Final]
	at io.netty.channel.kqueue.AbstractKQueueStreamChannel.doWrite(AbstractKQueueStreamChannel.java:274) ~[netty-transport-native-kqueue-4.1.55.Final-osx-x86_64.jar:4.1.55.Final]

Steps to reproduce are same, just use spring boot 2.4.1.

@normanmaurer
Copy link
Member

@henrychv doh! We missed another place :/

@normanmaurer
Copy link
Member

@henrychv #10870

normanmaurer added a commit that referenced this issue Dec 16, 2020
Motivation:

#10814 did fix a bug where we did try to call memoryAddress() even tho this is not supported. Unfortunally this fix was only applied for one method and so we missed another method which then could throw an exception when we called memoryAddress()

Modifications:

- Also fix the memoryAddress(offset) method.
_ Adjust unit test to also test this.

Result:

Fixes #10813 completely.
@normanmaurer normanmaurer self-assigned this Dec 16, 2020
normanmaurer added a commit that referenced this issue Dec 16, 2020
Motivation:

#10814 did fix a bug where we did try to call memoryAddress() even tho this is not supported. Unfortunally this fix was only applied for one method and so we missed another method which then could throw an exception when we called memoryAddress()

Modifications:

- Also fix the memoryAddress(offset) method.
_ Adjust unit test to also test this.

Result:

Fixes #10813 completely.
normanmaurer added a commit that referenced this issue Dec 16, 2020
Motivation:

#10814 did fix a bug where we did try to call memoryAddress() even tho this is not supported. Unfortunally this fix was only applied for one method and so we missed another method which then could throw an exception when we called memoryAddress()

Modifications:

- Also fix the memoryAddress(offset) method.
_ Adjust unit test to also test this.

Result:

Fixes #10813 completely.
raidyue pushed a commit to raidyue/netty that referenced this issue Jul 8, 2022
Motivation:

In some enviroments sun.misc.Unsafe is not present. We should support these as well.

Modifications:

Fallback to JNI if we can't directly access the memoryAddress of the buffer.

Result:

Fixes netty#10813
raidyue pushed a commit to raidyue/netty that referenced this issue Jul 8, 2022
Motivation:

netty#10814 did fix a bug where we did try to call memoryAddress() even tho this is not supported. Unfortunally this fix was only applied for one method and so we missed another method which then could throw an exception when we called memoryAddress()

Modifications:

- Also fix the memoryAddress(offset) method.
_ Adjust unit test to also test this.

Result:

Fixes netty#10813 completely.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants