mirror of https://github.com/grpc/grpc-java.git
Don't use reflection for epoll/unix domain sockets
The classes are available, even on Windows. Trying to use them though won't work. You'll get an error like: java.lang.UnsatisfiedLinkError: no netty-transport-native-epoll in java.library.path
This commit is contained in:
parent
3af3d1bee3
commit
65d73c0dc2
|
|
@ -39,12 +39,9 @@ dependencies {
|
||||||
project(':grpc-interop-testing'),
|
project(':grpc-interop-testing'),
|
||||||
libraries.junit,
|
libraries.junit,
|
||||||
libraries.mockito,
|
libraries.mockito,
|
||||||
libraries.hdrhistogram
|
libraries.hdrhistogram,
|
||||||
if (osdetector.os == "linux") {
|
libraries.netty_tcnative,
|
||||||
// These are only available on linux.
|
libraries.netty_transport_native_epoll
|
||||||
compile libraries.netty_tcnative,
|
|
||||||
libraries.netty_transport_native_epoll
|
|
||||||
}
|
|
||||||
|
|
||||||
alpnboot alpnboot_package_name
|
alpnboot alpnboot_package_name
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,12 @@ import io.grpc.transport.netty.NegotiationType;
|
||||||
import io.grpc.transport.netty.NettyChannelBuilder;
|
import io.grpc.transport.netty.NettyChannelBuilder;
|
||||||
import io.grpc.transport.okhttp.OkHttpChannelBuilder;
|
import io.grpc.transport.okhttp.OkHttpChannelBuilder;
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.epoll.EpollDomainSocketChannel;
|
||||||
|
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||||
|
import io.netty.channel.epoll.EpollSocketChannel;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.channel.unix.DomainSocketAddress;
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
|
|
||||||
|
|
@ -79,24 +83,22 @@ final class Utils {
|
||||||
static SocketAddress parseSocketAddress(String value) {
|
static SocketAddress parseSocketAddress(String value) {
|
||||||
if (value.startsWith(UNIX_DOMAIN_SOCKET_PREFIX)) {
|
if (value.startsWith(UNIX_DOMAIN_SOCKET_PREFIX)) {
|
||||||
// Unix Domain Socket address.
|
// Unix Domain Socket address.
|
||||||
|
// Create the underlying file for the Unix Domain Socket.
|
||||||
|
String filePath = value.substring(UNIX_DOMAIN_SOCKET_PREFIX.length());
|
||||||
|
File file = new File(filePath);
|
||||||
|
if (!file.isAbsolute()) {
|
||||||
|
throw new IllegalArgumentException("File path must be absolute: " + filePath);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// Create the underlying file for the Unix Domain Socket.
|
|
||||||
String filePath = value.substring(UNIX_DOMAIN_SOCKET_PREFIX.length());
|
|
||||||
File file = new File(filePath);
|
|
||||||
if (!file.isAbsolute()) {
|
|
||||||
throw new IllegalArgumentException("File path must be absolute: " + filePath);
|
|
||||||
}
|
|
||||||
if (file.createNewFile()) {
|
if (file.createNewFile()) {
|
||||||
// If this application created the file, delete it when the application exits.
|
// If this application created the file, delete it when the application exits.
|
||||||
file.deleteOnExit();
|
file.deleteOnExit();
|
||||||
}
|
}
|
||||||
// Create the SocketAddress referencing the file.
|
} catch (IOException ex) {
|
||||||
Class<?> addressClass = Class.forName("io.netty.channel.unix.DomainSocketAddress");
|
throw new RuntimeException(ex);
|
||||||
return (SocketAddress) addressClass.getDeclaredConstructor(File.class)
|
|
||||||
.newInstance(file);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
// Create the SocketAddress referencing the file.
|
||||||
|
return new DomainSocketAddress(file);
|
||||||
} else {
|
} else {
|
||||||
// Standard TCP/IP address.
|
// Standard TCP/IP address.
|
||||||
String[] parts = value.split(":", 2);
|
String[] parts = value.split(":", 2);
|
||||||
|
|
@ -146,45 +148,26 @@ final class Utils {
|
||||||
final EventLoopGroup group;
|
final EventLoopGroup group;
|
||||||
final Class<? extends io.netty.channel.Channel> channelType;
|
final Class<? extends io.netty.channel.Channel> channelType;
|
||||||
switch (config.transport) {
|
switch (config.transport) {
|
||||||
case NETTY_NIO: {
|
case NETTY_NIO:
|
||||||
group = new NioEventLoopGroup();
|
group = new NioEventLoopGroup();
|
||||||
channelType = NioSocketChannel.class;
|
channelType = NioSocketChannel.class;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case NETTY_EPOLL: {
|
case NETTY_EPOLL:
|
||||||
try {
|
// These classes only work on Linux.
|
||||||
// These classes are only available on linux.
|
group = new EpollEventLoopGroup();
|
||||||
Class<?> groupClass = Class.forName("io.netty.channel.epoll.EpollEventLoopGroup");
|
channelType = EpollSocketChannel.class;
|
||||||
@SuppressWarnings("unchecked")
|
break;
|
||||||
Class<? extends io.netty.channel.Channel> channelClass =
|
|
||||||
(Class<? extends io.netty.channel.Channel>) Class.forName(
|
case NETTY_UNIX_DOMAIN_SOCKET:
|
||||||
"io.netty.channel.epoll.EpollSocketChannel");
|
// These classes only work on Linux.
|
||||||
group = (EventLoopGroup) groupClass.newInstance();
|
group = new EpollEventLoopGroup();
|
||||||
channelType = channelClass;
|
channelType = EpollDomainSocketChannel.class;
|
||||||
break;
|
break;
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
default:
|
||||||
}
|
|
||||||
}
|
|
||||||
case NETTY_UNIX_DOMAIN_SOCKET: {
|
|
||||||
try {
|
|
||||||
// These classes are only available on linux.
|
|
||||||
Class<?> groupClass = Class.forName("io.netty.channel.epoll.EpollEventLoopGroup");
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Class<? extends io.netty.channel.Channel> channelClass =
|
|
||||||
(Class<? extends io.netty.channel.Channel>) Class.forName(
|
|
||||||
"io.netty.channel.epoll.EpollDomainSocketChannel");
|
|
||||||
group = (EventLoopGroup) groupClass.newInstance();
|
|
||||||
channelType = channelClass;
|
|
||||||
break;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
// Should never get here.
|
// Should never get here.
|
||||||
throw new IllegalArgumentException("Unsupported transport: " + config.transport);
|
throw new IllegalArgumentException("Unsupported transport: " + config.transport);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NettyChannelBuilder
|
return NettyChannelBuilder
|
||||||
.forAddress(config.address)
|
.forAddress(config.address)
|
||||||
|
|
|
||||||
14
build.gradle
14
build.gradle
|
|
@ -93,6 +93,16 @@ subprojects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def tcnative_suffix = "";
|
||||||
|
if (osdetector.classifier in ["linux-x86_64", "osx-x86_64", "windows-x86_64"]) {
|
||||||
|
// The native code is only pre-compiled on certain platforms.
|
||||||
|
tcnative_suffix = ":" + osdetector.classifier
|
||||||
|
}
|
||||||
|
def epoll_suffix = "";
|
||||||
|
if (osdetector.classifier in ["linux-x86_64"]) {
|
||||||
|
// The native code is only pre-compiled on certain platforms.
|
||||||
|
epoll_suffix = ":" + osdetector.classifier
|
||||||
|
}
|
||||||
libraries = [
|
libraries = [
|
||||||
guava: 'com.google.guava:guava:18.0',
|
guava: 'com.google.guava:guava:18.0',
|
||||||
// used to collect benchmark results
|
// used to collect benchmark results
|
||||||
|
|
@ -108,8 +118,8 @@ subprojects {
|
||||||
protobuf_plugin: 'com.google.protobuf:protobuf-gradle-plugin:0.4.1',
|
protobuf_plugin: 'com.google.protobuf:protobuf-gradle-plugin:0.4.1',
|
||||||
|
|
||||||
netty: 'io.netty:netty-codec-http2:4.1.0.Beta5',
|
netty: 'io.netty:netty-codec-http2:4.1.0.Beta5',
|
||||||
netty_tcnative: "io.netty:netty-tcnative:1.1.33.Fork2:${osdetector.classifier}",
|
netty_tcnative: 'io.netty:netty-tcnative:1.1.33.Fork2' + tcnative_suffix,
|
||||||
netty_transport_native_epoll: "io.netty:netty-transport-native-epoll:4.1.0.Beta5:${osdetector.classifier}",
|
netty_transport_native_epoll: 'io.netty:netty-transport-native-epoll:4.1.0.Beta5' + epoll_suffix,
|
||||||
|
|
||||||
// Test dependencies.
|
// Test dependencies.
|
||||||
junit: 'junit:junit:4.11',
|
junit: 'junit:junit:4.11',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue