-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #634 from michael-simons/feature/improve-shaded-ne…
…tty-native Add support for native compilation.
- Loading branch information
Showing
6 changed files
with
459 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
312 changes: 312 additions & 0 deletions
312
driver/src/main/java/org/neo4j/driver/internal/svm/NettySubstitutions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,312 @@ | ||
/* | ||
* Copyright (c) 2002-2019 "Neo4j," | ||
* Neo4j Sweden AB [http://neo4j.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.neo4j.driver.internal.svm; | ||
|
||
import com.oracle.svm.core.annotate.Alias; | ||
import com.oracle.svm.core.annotate.Substitute; | ||
import com.oracle.svm.core.annotate.TargetClass; | ||
import com.oracle.svm.core.jdk.JDK11OrLater; | ||
|
||
import java.security.PrivateKey; | ||
import java.security.Provider; | ||
import java.security.cert.X509Certificate; | ||
import java.util.Queue; | ||
import java.util.concurrent.LinkedBlockingDeque; | ||
import javax.net.ssl.KeyManagerFactory; | ||
import javax.net.ssl.SSLEngine; | ||
import javax.net.ssl.SSLException; | ||
import javax.net.ssl.TrustManagerFactory; | ||
|
||
import io.netty.bootstrap.AbstractBootstrapConfig; | ||
import io.netty.bootstrap.ChannelFactory; | ||
import io.netty.buffer.ByteBufAllocator; | ||
import io.netty.channel.Channel; | ||
import io.netty.channel.ChannelFuture; | ||
import io.netty.channel.DefaultChannelPromise; | ||
import io.netty.handler.ssl.ApplicationProtocolConfig; | ||
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; | ||
import io.netty.handler.ssl.CipherSuiteFilter; | ||
import io.netty.handler.ssl.ClientAuth; | ||
import io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator; | ||
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator; | ||
import io.netty.handler.ssl.SslContext; | ||
import io.netty.handler.ssl.SslProvider; | ||
import io.netty.util.concurrent.GlobalEventExecutor; | ||
import io.netty.util.internal.logging.InternalLoggerFactory; | ||
import io.netty.util.internal.logging.JdkLoggerFactory; | ||
|
||
/** | ||
* This substitution avoid having loggers added to the build | ||
*/ | ||
@TargetClass(className = "io.netty.util.internal.logging.InternalLoggerFactory") | ||
final class Target_io_netty_util_internal_logging_InternalLoggerFactory { | ||
|
||
@Substitute | ||
private static InternalLoggerFactory newDefaultFactory( String name) { | ||
return JdkLoggerFactory.INSTANCE; | ||
} | ||
} | ||
|
||
// SSL | ||
// This whole section is mostly about removing static analysis references to openssl/tcnative | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.JdkSslServerContext") | ||
final class Target_io_netty_handler_ssl_JdkSslServerContext { | ||
|
||
@Alias | ||
Target_io_netty_handler_ssl_JdkSslServerContext( Provider provider, | ||
X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, | ||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, | ||
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter, | ||
ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, | ||
ClientAuth clientAuth, String[] protocols, boolean startTls, | ||
String keyStore) | ||
throws SSLException | ||
{ | ||
} | ||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.JdkSslClientContext") | ||
final class Target_io_netty_handler_ssl_JdkSslClientContext { | ||
|
||
@Alias | ||
Target_io_netty_handler_ssl_JdkSslClientContext( Provider sslContextProvider, | ||
X509Certificate[] trustCertCollection, | ||
TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, | ||
String keyPassword, KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, | ||
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, | ||
long sessionCacheSize, long sessionTimeout, String keyStoreType) | ||
throws SSLException | ||
{ | ||
|
||
} | ||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.SslHandler$SslEngineType") | ||
final class Target_io_netty_handler_ssl_SslHandler$SslEngineType { | ||
|
||
@Alias | ||
public static Target_io_netty_handler_ssl_SslHandler$SslEngineType JDK; | ||
|
||
@Substitute | ||
static Target_io_netty_handler_ssl_SslHandler$SslEngineType forEngine( SSLEngine engine) { | ||
return JDK; | ||
} | ||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", onlyWith = JDK11OrLater.class) | ||
final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper { | ||
@Substitute | ||
@SuppressWarnings( "deprecation" ) | ||
public SSLEngine wrapSslEngine( SSLEngine engine, ByteBufAllocator alloc, | ||
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { | ||
return (SSLEngine) (Object) new Target_io_netty_handler_ssl_Java9SslEngine( | ||
engine, applicationNegotiator, isServer); | ||
} | ||
|
||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.Java9SslEngine", onlyWith = JDK11OrLater.class) | ||
final class Target_io_netty_handler_ssl_Java9SslEngine { | ||
@Alias | ||
@SuppressWarnings( "deprecation" ) | ||
Target_io_netty_handler_ssl_Java9SslEngine(final SSLEngine engine, | ||
final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { | ||
|
||
} | ||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.SslContext") | ||
final class Target_io_netty_handler_ssl_SslContext { | ||
|
||
@Substitute | ||
static SslContext newServerContextInternal(SslProvider provider, | ||
Provider sslContextProvider, | ||
X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, | ||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, | ||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, | ||
long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, | ||
boolean enableOcsp, String keyStoreType) | ||
throws SSLException | ||
{ | ||
|
||
if (enableOcsp) { | ||
throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); | ||
} | ||
return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslServerContext( | ||
sslContextProvider, | ||
trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, | ||
keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, | ||
clientAuth, protocols, startTls, keyStoreType); | ||
} | ||
|
||
@Substitute | ||
static SslContext newClientContextInternal( | ||
SslProvider provider, | ||
Provider sslContextProvider, | ||
X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory, | ||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, | ||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, | ||
long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStoreType) throws SSLException | ||
{ | ||
if (enableOcsp) { | ||
throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); | ||
} | ||
return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext( | ||
sslContextProvider, | ||
trustCert, trustManagerFactory, keyCertChain, key, keyPassword, | ||
keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, | ||
sessionTimeout, keyStoreType); | ||
} | ||
|
||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.JdkDefaultApplicationProtocolNegotiator") | ||
final class Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator { | ||
|
||
@Alias | ||
public static Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator INSTANCE; | ||
} | ||
|
||
@TargetClass(className = "io.netty.handler.ssl.JdkSslContext") | ||
final class Target_io_netty_handler_ssl_JdkSslContext { | ||
|
||
@Substitute | ||
static JdkApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config, boolean isServer) { | ||
if (config == null) { | ||
return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; | ||
} | ||
|
||
switch (config.protocol()) { | ||
case NONE: | ||
return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; | ||
case ALPN: | ||
if (isServer) { | ||
// GRAAL RC9 bug: https://github.com/oracle/graal/issues/813 | ||
// switch(config.selectorFailureBehavior()) { | ||
// case FATAL_ALERT: | ||
// return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); | ||
// case NO_ADVERTISE: | ||
// return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); | ||
// default: | ||
// throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") | ||
// .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); | ||
// } | ||
SelectorFailureBehavior behavior = config.selectorFailureBehavior(); | ||
if (behavior == SelectorFailureBehavior.FATAL_ALERT) | ||
return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); | ||
else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) | ||
return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); | ||
else { | ||
throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") | ||
.append(config.selectorFailureBehavior()).append(" failure behavior").toString()); | ||
} | ||
} else { | ||
switch (config.selectedListenerFailureBehavior()) { | ||
case ACCEPT: | ||
return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); | ||
case FATAL_ALERT: | ||
return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); | ||
default: | ||
throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") | ||
.append(config.selectedListenerFailureBehavior()).append(" failure behavior") | ||
.toString()); | ||
} | ||
} | ||
default: | ||
throw new UnsupportedOperationException( | ||
new StringBuilder("JDK provider does not support ").append(config.protocol()).append(" protocol") | ||
.toString()); | ||
} | ||
} | ||
|
||
} | ||
|
||
/* | ||
* This one only prints exceptions otherwise we get a useless bogus | ||
* exception message: https://github.com/eclipse-vertx/vert.x/issues/1657 | ||
*/ | ||
@TargetClass(className = "io.netty.bootstrap.AbstractBootstrap") | ||
final class Target_io_netty_bootstrap_AbstractBootstrap { | ||
|
||
@Alias | ||
private ChannelFactory channelFactory; | ||
|
||
@Alias | ||
void init(Channel channel) throws Exception | ||
{ | ||
} | ||
|
||
@Alias | ||
public AbstractBootstrapConfig config() { | ||
return null; | ||
} | ||
|
||
@Substitute | ||
final ChannelFuture initAndRegister() { | ||
Channel channel = null; | ||
try { | ||
channel = channelFactory.newChannel(); | ||
init(channel); | ||
} catch ( Throwable t) { | ||
// THE FIX IS HERE: | ||
t.printStackTrace(); | ||
if (channel != null) { | ||
// channel can be null if newChannel crashed (eg SocketException("too many open files")) | ||
channel.unsafe().closeForcibly(); | ||
} | ||
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor | ||
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t); | ||
} | ||
|
||
ChannelFuture regFuture = config().group().register(channel); | ||
if (regFuture.cause() != null) { | ||
if (channel.isRegistered()) { | ||
channel.close(); | ||
} else { | ||
channel.unsafe().closeForcibly(); | ||
} | ||
} | ||
|
||
// If we are here and the promise is not failed, it's one of the following cases: | ||
// 1) If we attempted registration from the event loop, the registration has been completed at this point. | ||
// i.e. It's safe to attempt bind() or connect() now because the channel has been registered. | ||
// 2) If we attempted registration from the other thread, the registration request has been successfully | ||
// added to the event loop's task queue for later execution. | ||
// i.e. It's safe to attempt bind() or connect() now: | ||
// because bind() or connect() will be executed *after* the scheduled registration task is executed | ||
// because register(), bind(), and connect() are all bound to the same thread. | ||
|
||
return regFuture; | ||
|
||
} | ||
} | ||
|
||
@TargetClass(className = "io.netty.channel.nio.NioEventLoop") | ||
final class Target_io_netty_channel_nio_NioEventLoop { | ||
|
||
@Substitute | ||
private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) { | ||
return new LinkedBlockingDeque<>(); | ||
} | ||
} | ||
|
||
class NettySubstitutions { | ||
|
||
} |
Oops, something went wrong.