Add workaround for possible classloader deadlock when trying to load JNI code (#10190)
Motivation: netty_epoll_linuxsocket_JNI_OnLoad(...) may produce a deadlock with another thread that will load IOUtil in a static block. This seems to be a JDK bug which is not yet fixed. To workaround this we force IOUtil to be loaded from without java code before init the JNI code Modifications: Use Selector.open() as a workaround to load IOUtil Result: Fixes https://github.com/netty/netty/issues/10187
This commit is contained in:
parent
fb5e2cd3aa
commit
6dad12defa
@ -25,6 +25,7 @@ import io.netty.util.internal.logging.InternalLogger;
|
|||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.Selector;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static io.netty.channel.epoll.NativeStaticallyReferencedJniMethods.epollerr;
|
import static io.netty.channel.epoll.NativeStaticallyReferencedJniMethods.epollerr;
|
||||||
@ -49,6 +50,16 @@ public final class Native {
|
|||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Native.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Native.class);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
Selector selector = null;
|
||||||
|
try {
|
||||||
|
// We call Selector.open() as this will under the hood cause IOUtil to be loaded.
|
||||||
|
// This is a workaround for a possible classloader deadlock that could happen otherwise:
|
||||||
|
//
|
||||||
|
// See https://github.com/netty/netty/issues/10187
|
||||||
|
selector = Selector.open();
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
// Just ignore
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// First, try calling a side-effect free JNI method to see if the library was already
|
// First, try calling a side-effect free JNI method to see if the library was already
|
||||||
// loaded by the application.
|
// loaded by the application.
|
||||||
@ -56,6 +67,14 @@ public final class Native {
|
|||||||
} catch (UnsatisfiedLinkError ignore) {
|
} catch (UnsatisfiedLinkError ignore) {
|
||||||
// The library was not previously loaded, load it now.
|
// The library was not previously loaded, load it now.
|
||||||
loadNativeLibrary();
|
loadNativeLibrary();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (selector != null) {
|
||||||
|
selector.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
// Just ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Socket.initialize();
|
Socket.initialize();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user