Skip to content

Move polymorphic VarHandle calls to separate class to avoid Android v…#15661

Merged
normanmaurer merged 1 commit into
4.2from
fix/android-varhandle-verifyerror-15654
Sep 16, 2025
Merged

Move polymorphic VarHandle calls to separate class to avoid Android v…#15661
normanmaurer merged 1 commit into
4.2from
fix/android-varhandle-verifyerror-15654

Conversation

@yawkat

@yawkat yawkat commented Sep 15, 2025

Copy link
Copy Markdown
Contributor

…erification error

Motivation:

Android 8–12 ART/Dalvik rejects classes with direct signature-polymorphic VarHandle call sites. After upgrading Netty to 4.2.4+, UnpooledDirectByteBuf triggers a java.lang.VerifyError when its methods reference ByteBuffer VarHandle view operations, even if VarHandles are disabled via -Dio.netty.varHandle.enabled=false. As suggested by yawkat in #15654, the fix is to move VarHandle usage into a separate class and only load it when VarHandles are actually available.

Modification:

  • Introduce VarHandleByteBufferAccess to centralize all ByteBuffer VarHandle get/set operations.
  • Update UnpooledDirectByteBuf to:
    • Guard VarHandle paths with PlatformDependent.hasVarHandle().
    • Delegate to VarHandleByteBufferAccess for get/set of short/int/long (BE/LE).
    • Fall back to ByteBuffer methods (and byte-order swaps) when VarHandles are unavailable.
    • Remove direct VarHandle import to avoid embedding signature-polymorphic call sites in this class.
  • No behavioral changes on platforms with working VarHandles; Android 8–12 avoids verifier failures by not loading the helper class.

Touched methods in UnpooledDirectByteBuf: _getShort, _getShortLE, _getInt, _getIntLE, _getLong, _getLongLE, _setShort, _setShortLE, _setInt, _setIntLE, _setLong, _setLongLE.

Result:

Fixes #15654.


I threw AI at the problem and told it to fix the issue according to my comment on the issue thread. @ajith211, please try this fix. You'll have to build netty locally to test it though.

…erification error

Motivation:

Android 8–12 ART/Dalvik rejects classes with direct signature-polymorphic VarHandle call sites. After upgrading Netty to 4.2.4+, UnpooledDirectByteBuf triggers a java.lang.VerifyError when its methods reference ByteBuffer VarHandle view operations, even if VarHandles are disabled via -Dio.netty.varHandle.enabled=false. As suggested by yawkat in #15654, the fix is to move VarHandle usage into a separate class and only load it when VarHandles are actually available.

Modification:

- Introduce VarHandleByteBufferAccess to centralize all ByteBuffer VarHandle get/set operations.
- Update UnpooledDirectByteBuf to:
  - Guard VarHandle paths with PlatformDependent.hasVarHandle().
  - Delegate to VarHandleByteBufferAccess for get/set of short/int/long (BE/LE).
  - Fall back to ByteBuffer methods (and byte-order swaps) when VarHandles are unavailable.
  - Remove direct VarHandle import to avoid embedding signature-polymorphic call sites in this class.
- No behavioral changes on platforms with working VarHandles; Android 8–12 avoids verifier failures by not loading the helper class.

Touched methods in UnpooledDirectByteBuf: _getShort, _getShortLE, _getInt, _getIntLE, _getLong, _getLongLE, _setShort, _setShortLE, _setInt, _setIntLE, _setLong, _setLongLE.

Result:

Fixes #15654.
Comment thread buffer/src/main/java/io/netty/buffer/VarHandleByteBufferAccess.java Dismissed

@franz1981 franz1981 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, it shouldn't change behaviour for hotspot, if not that we have another method to compile but very minimal (likely in the small inline level)

@normanmaurer

Copy link
Copy Markdown
Member

@yawkat I think we still need to disable VarHandles on android by default imho

@yawkat

yawkat commented Sep 15, 2025

Copy link
Copy Markdown
Contributor Author

I'm not sure, I think the check that's already in place should be enough. A runtime that doesn't support polymorphic signatures for VarHandle is also unlikely to support VarHandle.storeStoreFence.

@normanmaurer

Copy link
Copy Markdown
Member

@yawkat maybe... maybe better be save then sorry ? But lets wait for the reporter to test it

@normanmaurer

Copy link
Copy Markdown
Member

I think this is good to go... Happy to merge ?

@yawkat

yawkat commented Sep 16, 2025

Copy link
Copy Markdown
Contributor Author

If you want to we can merge it speculatively, and have @ajith211 test with the snapshot. This PR at least shouldn't hurt anyone. But I don't know if it really works.

@yawkat yawkat marked this pull request as ready for review September 16, 2025 06:25
@normanmaurer

Copy link
Copy Markdown
Member

@yawkat yeah I think this would be the best... let me merge it

@normanmaurer normanmaurer merged commit f03179b into 4.2 Sep 16, 2025
19 checks passed
@normanmaurer normanmaurer deleted the fix/android-varhandle-verifyerror-15654 branch September 16, 2025 06:27
@ajith211

Copy link
Copy Markdown

If you want to we can merge it speculatively, and have @ajith211 test with the snapshot. This PR at least shouldn't hurt anyone. But I don't know if it really works.

If you can share a testable artifact, we can consume and verify the same.
Also could you please share the release plan of this fix ?

@ajith211

Copy link
Copy Markdown

Going forward, do we need to disable this varHandle flag on Android builds ?

@normanmaurer

Copy link
Copy Markdown
Member

If you want to we can merge it speculatively, and have @ajith211 test with the snapshot. This PR at least shouldn't hurt anyone. But I don't know if it really works.

If you can share a testable artifact, we can consume and verify the same. Also could you please share the release plan of this fix ?

Just try 4.2.7-SNAPSHOT

@normanmaurer

Copy link
Copy Markdown
Member

Going forward, do we need to disable this varHandle flag on Android builds ?

no

@ajith211

Copy link
Copy Markdown

If you want to we can merge it speculatively, and have @ajith211 test with the snapshot. This PR at least shouldn't hurt anyone. But I don't know if it really works.

If you can share a testable artifact, we can consume and verify the same. Also could you please share the release plan of this fix ?

Just try 4.2.7-SNAPSHOT

Applied <netty.version>4.2.7-SNAPSHOT</netty.version>
It's not available to consume
Could not find artifact io.netty:netty-common:pom:4.2.7-SNAPSHOT in sonatype-nexus-snapshots (https://oss.sonatype.org/content/repositories/snapshots)

@normanmaurer

Copy link
Copy Markdown
Member

If you want to we can merge it speculatively, and have @ajith211 test with the snapshot. This PR at least shouldn't hurt anyone. But I don't know if it really works.

If you can share a testable artifact, we can consume and verify the same. Also could you please share the release plan of this fix ?

Just try 4.2.7-SNAPSHOT

Applied <netty.version>4.2.7-SNAPSHOT</netty.version> It's not available to consume Could not find artifact io.netty:netty-common:pom:4.2.7-SNAPSHOT in sonatype-nexus-snapshots (https://oss.sonatype.org/content/repositories/snapshots)

We use maven central for snapshots:

https://central.sonatype.com/repository/maven-snapshots/

@normanmaurer

Copy link
Copy Markdown
Member

@ajith211 please keep us posted

@ajith211

Copy link
Copy Markdown

Not able to consume this artifact yet.
Applied below changes in the POM file

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<github.global.server>github</github.global.server>
<netty.version>4.2.7.Final-SNAPSHOT</netty.version>
<slf4j.version>1.7.30</slf4j.version>
<java.version>1.8</java.version>

**<repositories>
    <repository>
        <name>Central Portal Snapshots</name>
        <id>central-portal-snapshots</id>
        <url>https://central.sonatype.com/repository/maven-snapshots</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>**

[WARNING] Failed to download maven-metadata-central-portal-snapshots1.xml [https://central.sonatype.com/repositories/snapshots/]

@slandelle

Copy link
Copy Markdown
Contributor

Not <netty.version>4.2.7.Final-SNAPSHOT</netty.version> but 4.2.7-SNAPSHOT.

@normanmaurer

Copy link
Copy Markdown
Member

Not its '4.2.7.Final-SNAPSHOT'. As you can see it was deployed:

https://github.com/netty/netty/actions/runs/17756760347/job/50461461860

@ajith211

Copy link
Copy Markdown

Could not find artifact io.netty:netty-codec-socks:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-buffer:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-codec:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-codec-http:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-common:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-handler:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-transport:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)
Could not find artifact io.netty:netty-all:jar:4.2.7-SNAPSHOT in central-portal-snapshots (https://central.sonatype.com/repository/maven-snapshots/)

@normanmaurer

Copy link
Copy Markdown
Member

alternative just install it ./mvnw -pl common, buffer clean install -DskipTests=true

@ajith211

Copy link
Copy Markdown

Not its '4.2.7.Final-SNAPSHOT'. As you can see it was deployed:

https://github.com/netty/netty/actions/runs/17756760347/job/50461461860

I am bit confused about the snapshot artifact by seeing below log
https://github.com/netty/netty/actions/runs/17756760347/job/50461461860#logs
Screenshot 2025-09-16 at 11 03 47 PM
So the question is whether it's deployed as 4.2.7.Final-SNAPSHOT or 4.2.7-SNAPSHOT ?

@ajith211

Copy link
Copy Markdown

I could able to consume 4.2.7.Final-SNAPSHOT but the problem is still present with this version.

@normanmaurer

Copy link
Copy Markdown
Member

Can you paste the stacktrace / error?

@ajith211

Copy link
Copy Markdown

Rejecting re-init on previously-failed class java.lang.Class<io.netty.buffer.HeapByteBufUtil>: java.lang.VerifyError: Verifier rejected class io.netty.buffer.HeapByteBufUtil: int io.netty.buffer.HeapByteBufUtil.getInt(byte[], int) failed to verify: int io.netty.buffer.HeapByteBufUtil.getInt(byte[], int): [0xF] int io.netty.buffer.HeapByteBufUtil.getInt(byte[], int): [0xF] register v5 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I int io.netty.buffer.HeapByteBufUtil.getIntLE(byte[], int) failed to verify: int io.netty.buffer.HeapByteBufUtil.getIntLE(byte[], int): [0xF] int io.netty.buffer.HeapByteBufUtil.getIntLE(byte[], int): [0xF] register v5 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I long io.netty.buffer.HeapByteBufUtil.getLong(byte[], int) failed to verify: long io.netty.buffer.HeapByteBufUtil.getLong(byte[], int): [0xF] long io.netty.buffer.HeapByteBufUtil.getLong(byte[], int): [0xF] register v6 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I long io.netty.buffer.HeapByteBufUtil.getLongLE(byte[], int) failed to verify: long io.netty.buffer.HeapByteBufUtil.getLongLE(byte[], int): [0xF] long io.netty.buffer.HeapByteBufUtil.getLongLE(byte[], int): [0xF] register v6 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I short io.netty.buffer.HeapByteBufUtil.getShort(byte[], int) failed to verify: short io.netty.buffer.HeapByteBufUtil.getShort(byte[], int): [0xD] short io.netty.buffer.HeapByteBufUtil.getShort(byte[], int): [0xD] register v5 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I short io.netty.buffer.HeapByteBufUtil.getShortLE(byte[], int) failed to verify: short io.netty.buffer.HeapByteBufUtil.getShortLE(byte[], int): [0xE] short io.netty.buffer.HeapByteBufUtil.getShortLE(byte[], int): [0xE] register v5 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I void io.netty.buffer.HeapByteBufUtil.setInt(byte[], int, int) failed to verify: void io.netty.buffer.HeapByteBufUtil.setInt(byte[], int, int): [0xF] void io.netty.buffer.HeapByteBufUtil.setInt(byte[], int, int): [0xF] register v4 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I void io.netty.buffer.HeapByteBufUtil.setIntLE(byte[], int, int) failed to verify: void io.netty.buffer.HeapByteBufUtil.setIntLE(byte[], int, int): [0xF] void io.netty.buffer.HeapByteBufUtil.setIntLE(byte[], int, int): [0xF] register v4 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I void io.netty.buffer.HeapByteBufUtil.setLong(byte[], int, long) failed to verify: void io.netty.buffer.HeapByteBufUtil.setLong(byte[], int, long): [0xF] void io.netty.buffer.HeapByteBufUtil.setLong(byte[], int, long): [0xF] register v4 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I void io.netty.buffer.HeapByteBufUtil.setLongLE(byte[], int, long) failed to verify: void io.netty.buffer.HeapByteBufUtil.setLongLE(byte[], int, long): [0xF] void io.netty.buffer.HeapByteBufUtil.setLongLE(byte[], int, long): [0xF] register v4 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I void io.netty.buffer.HeapByteBufUtil.setShort(byte[], int, int) failed to verify: void io.netty.buffer.HeapByteBufUtil.setShort(byte[], int, int): [0x10] void io.netty.buffer.HeapByteBufUtil.setShort(byte[], int, int): [0x10] register v5 has type Precise Reference: byte[] but expected Reference: java.lang.Object[]
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I void io.netty.buffer.HeapByteBufUtil.setShortLE(byte[], int, int) failed to verify: void io.netty.buffer.HeapByteBufUtil.setShortLE(byte[], int, int): [0x10] void io.netty.buffer.HeapByteBufUtil.setShortLE(byte[], int, int): [0x10] register v5 has type Precise Reference: byte[] but expected Reference: java.lang.Object[] (declaration of 'io.netty.buffer.HeapByteBufUtil' appears in /data/app/com.sample.airwatchsdk-2llbnJxUq1gZ0uqlg7snuw==/base.apk!classes34.dex)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.buffer.HeapByteBufUtil.setByte(byte[], int, int) (HeapByteBufUtil.java:-1)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.buffer.UnpooledHeapByteBuf._setByte(int, int) (UnpooledHeapByteBuf.java:433)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.buffer.AdaptivePoolingAllocator$AdaptiveByteBuf._setByte(int, int) (AdaptivePoolingAllocator.java:1715)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.buffer.ByteBuf io.netty.buffer.AbstractByteBuf.writeByte(int) (AbstractByteBuf.java:992)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.http.HttpResponseEncoder.encodeInitialLine(io.netty.buffer.ByteBuf, io.netty.handler.codec.http.HttpResponse) (HttpResponseEncoder.java:47)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.http.HttpResponseEncoder.encodeInitialLine(io.netty.buffer.ByteBuf, io.netty.handler.codec.http.HttpMessage) (HttpResponseEncoder.java:27)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.http.HttpObjectEncoder.encodeFullHttpMessage(io.netty.channel.ChannelHandlerContext, java.lang.Object, java.util.List) (HttpObjectEncoder.java:334)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.http.HttpObjectEncoder.encode(io.netty.channel.ChannelHandlerContext, java.lang.Object, java.util.List) (HttpObjectEncoder.java:169)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.http.HttpObjectEncoder.write(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.channel.ChannelPromise) (HttpObjectEncoder.java:104)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.AbstractChannelHandlerContext.write(java.lang.Object, boolean, io.netty.channel.ChannelPromise) (AbstractChannelHandlerContext.java:827)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelFuture io.netty.channel.AbstractChannelHandlerContext.write(java.lang.Object, io.netty.channel.ChannelPromise) (AbstractChannelHandlerContext.java:752)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.ChannelOutboundHandlerAdapter.write(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.channel.ChannelPromise) (ChannelOutboundHandlerAdapter.java:113)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection$ResponseWrittenMonitor.write(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.channel.ChannelPromise) (ProxyConnection.java:832)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.AbstractChannelHandlerContext.write(java.lang.Object, boolean, io.netty.channel.ChannelPromise) (AbstractChannelHandlerContext.java:827)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelFuture io.netty.channel.AbstractChannelHandlerContext.write(java.lang.Object, io.netty.channel.ChannelPromise) (AbstractChannelHandlerContext.java:752)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.timeout.IdleStateHandler.write(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.channel.ChannelPromise) (IdleStateHandler.java:309)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.AbstractChannelHandlerContext.write(java.lang.Object, boolean, io.netty.channel.ChannelPromise) (AbstractChannelHandlerContext.java:825)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelFuture io.netty.channel.AbstractChannelHandlerContext.write(java.lang.Object) (AbstractChannelHandlerContext.java:746)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelFuture io.netty.channel.DefaultChannelPipeline.write(java.lang.Object) (DefaultChannelPipeline.java:1031)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelFuture io.netty.channel.Channel.write(java.lang.Object) (Channel.java:272)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection.writeHttp(io.netty.handler.codec.http.HttpObject) (ProxyConnection.java:248)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection.doWrite(java.lang.Object) (ProxyConnection.java:232)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection.write(java.lang.Object) (ProxyConnection.java:224)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at boolean org.littleshoot.proxy.impl.ClientToProxyConnection.respondWithShortCircuitResponse(io.netty.handler.codec.http.HttpResponse) (ClientToProxyConnection.java:1302)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at boolean org.littleshoot.proxy.impl.ClientToProxyConnection.writeBadGateway(io.netty.handler.codec.http.HttpRequest) (ClientToProxyConnection.java:1225)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at org.littleshoot.proxy.impl.ConnectionState org.littleshoot.proxy.impl.ClientToProxyConnection.doReadHTTPInitial(io.netty.handler.codec.http.HttpRequest) (ClientToProxyConnection.java:322)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at org.littleshoot.proxy.impl.ConnectionState org.littleshoot.proxy.impl.ClientToProxyConnection.readHTTPInitial(io.netty.handler.codec.http.HttpRequest) (ClientToProxyConnection.java:206)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at org.littleshoot.proxy.impl.ConnectionState org.littleshoot.proxy.impl.ClientToProxyConnection.readHTTPInitial(io.netty.handler.codec.http.HttpObject) (ClientToProxyConnection.java:80)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection.readHTTP(io.netty.handler.codec.http.HttpObject) (ProxyConnection.java:135)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection.read(java.lang.Object) (ProxyConnection.java:120)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection.channelRead0(io.netty.channel.ChannelHandlerContext, java.lang.Object) (ProxyConnection.java:587)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.SimpleChannelInboundHandler.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (SimpleChannelInboundHandler.java:99)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelHandlerContext io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(java.lang.Object) (AbstractChannelHandlerContext.java:356)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.timeout.IdleStateHandler.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (IdleStateHandler.java:293)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelHandlerContext io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(java.lang.Object) (AbstractChannelHandlerContext.java:354)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.ChannelInboundHandlerAdapter.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (ChannelInboundHandlerAdapter.java:93)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection$RequestReadMonitor.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (ProxyConnection.java:715)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelHandlerContext io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(java.lang.Object) (AbstractChannelHandlerContext.java:356)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(io.netty.channel.ChannelHandlerContext, io.netty.handler.codec.CodecOutputList, int) (ByteToMessageDecoder.java:346)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.handler.codec.ByteToMessageDecoder.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (ByteToMessageDecoder.java:318)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelHandlerContext io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(java.lang.Object) (AbstractChannelHandlerContext.java:356)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.ChannelInboundHandlerAdapter.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (ChannelInboundHandlerAdapter.java:93)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (ProxyConnection.java:692)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelHandlerContext io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(java.lang.Object) (AbstractChannelHandlerContext.java:356)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) (DefaultChannelPipeline.java:1429)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at io.netty.channel.ChannelPipeline io.netty.channel.DefaultChannelPipeline.fireChannelRead(java.lang.Object) (DefaultChannelPipeline.java:918)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read() (AbstractNioByteChannel.java:168)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.handle(io.netty.channel.IoRegistration, io.netty.channel.IoEvent) (AbstractNioChannel.java:445)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.nio.NioIoHandler$DefaultNioRegistration.handle(int) (NioIoHandler.java:381)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.nio.NioIoHandler.processSelectedKey(java.nio.channels.SelectionKey) (NioIoHandler.java:587)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at int io.netty.channel.nio.NioIoHandler.processSelectedKeysOptimized() (NioIoHandler.java:562)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at int io.netty.channel.nio.NioIoHandler.processSelectedKeys() (NioIoHandler.java:503)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at int io.netty.channel.nio.NioIoHandler.run(io.netty.channel.IoHandlerContext) (NioIoHandler.java:475)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at int io.netty.channel.SingleThreadIoEventLoop.runIo() (SingleThreadIoEventLoop.java:225)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.channel.SingleThreadIoEventLoop.run() (SingleThreadIoEventLoop.java:196)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.util.concurrent.SingleThreadEventExecutor$5.run() (SingleThreadEventExecutor.java:1193)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void io.netty.util.internal.ThreadExecutorMap$2.run() (ThreadExecutorMap.java:74)
2025-09-16 23:50:24.547 24416-24595 ple.airwatchsd com.sample.airwatchsdk I at void java.lang.Thread.run() (Thread.java:919)

@yawkat

yawkat commented Sep 16, 2025

Copy link
Copy Markdown
Contributor Author

Oh, that error mentions a different class, HeapByteBufUtil. I think this is good news – the fix likely worked, but I missed some call sites. I will try to throw AI at that problem too :)

yawkat added a commit that referenced this pull request Sep 16, 2025
Motivation:
Follow-up to #15661. Move signature-polymorphic VarHandle calls out of HeapByteBufUtil to avoid class verification issues on older Android runtimes when VarHandle is disabled.

Modifications:
- Add byte[] getters/setters to VarHandleByteBufferAccess that wrap PlatformDependent.*ArrayView() VarHandles.
- Use these methods from HeapByteBufUtil when VarHandle is enabled, preserving existing bitwise fallbacks otherwise.
- Remove direct signature-polymorphic calls from HeapByteBufUtil.

Result:
No direct references to signature-polymorphic VarHandle methods remain in HeapByteBufUtil. Behavior is unchanged when VarHandle is disabled.
normanmaurer pushed a commit that referenced this pull request Sep 17, 2025
…ss (#15670)

Motivation:

Follow-up to #15661. Move signature-polymorphic VarHandle calls out of
HeapByteBufUtil to avoid class verification issues on older Android
runtimes when VarHandle is disabled.

Modifications:

- Add byte[] getters/setters to VarHandleByteBufferAccess that wrap
PlatformDependent.*ArrayView() VarHandles.
- Use these methods from HeapByteBufUtil when VarHandle is enabled,
preserving existing bitwise fallbacks otherwise.
- Remove direct signature-polymorphic calls from HeapByteBufUtil.

Result:

No direct references to signature-polymorphic VarHandle methods remain
in HeapByteBufUtil. Behavior is unchanged when VarHandle is disabled.
@normanmaurer normanmaurer added this to the 4.2.7.Final milestone Sep 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

After upgrading Netty to 4.2.4+, application is throwing java.lang.VerifyError on Android platform 8/9/10/11/12

6 participants