[#5648] Detect if netty-tcnative is in classpath or just tcnative

Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
This commit is contained in:
Norman Maurer 2016-08-06 21:47:26 +02:00
parent 260e9ece90
commit 47d55339c9

View File

@ -24,12 +24,15 @@ import io.netty.util.internal.NativeLibraryLoader;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.apache.tomcat.Apr;
import org.apache.tomcat.jni.Buffer;
import org.apache.tomcat.jni.Library;
import org.apache.tomcat.jni.Pool;
import org.apache.tomcat.jni.SSL;
import org.apache.tomcat.jni.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@ -37,6 +40,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
/**
@ -120,6 +124,12 @@ public final class OpenSsl {
}
}
if (cause == null && !isNettyTcnative()) {
logger.debug("incompatible tcnative in the classpath; "
+ OpenSslEngine.class.getSimpleName() + " will be unavailable.");
cause = new ClassNotFoundException("incompatible tcnative in the classpath");
}
UNAVAILABILITY_CAUSE = cause;
if (cause == null) {
@ -206,6 +216,32 @@ public final class OpenSsl {
}
}
private static boolean isNettyTcnative() {
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
InputStream is = null;
try {
is = Apr.class.getResourceAsStream("/org/apache/tomcat/apr.properties");
Properties props = new Properties();
props.load(is);
String info = props.getProperty("tcn.info");
return info != null && info.startsWith("netty-tcnative");
} catch (Throwable ignore) {
return false;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignore) {
// ignore
}
}
}
}
});
}
/**
* Returns {@code true} if and only if
* <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support