Make Native loading work better with Java 8
Motivation: Enable static linking for Java 8. These commits are the same as those introduced to netty tcnative. The goal is to allow lots of JNI libraries to be statically linked together without having conflict `JNI_OnLoad` methods. Modification: * add JNI_OnLoad suffixes to enable static linking * Add static names to the list of libraries that try to be loaded * Enable compiling with JNI 1.8 * Sort includes Result: Enable statically linked JNI code.
This commit is contained in:
parent
c3bd1245c5
commit
83de77fbe5
@ -389,7 +389,7 @@ public final class OpenSsl {
|
||||
String os = normalizeOs(SystemPropertyUtil.get("os.name", ""));
|
||||
String arch = normalizeArch(SystemPropertyUtil.get("os.arch", ""));
|
||||
|
||||
Set<String> libNames = new LinkedHashSet<String>(3);
|
||||
Set<String> libNames = new LinkedHashSet<String>(4);
|
||||
// First, try loading the platform-specific library. Platform-specific
|
||||
// libraries will be available if using a tcnative uber jar.
|
||||
libNames.add("netty-tcnative-" + os + '-' + arch);
|
||||
@ -399,6 +399,8 @@ public final class OpenSsl {
|
||||
}
|
||||
// finally the default library.
|
||||
libNames.add("netty-tcnative");
|
||||
// in Java 8, statically compiled JNI code is namespaced
|
||||
libNames.add("netty_tcnative");
|
||||
|
||||
NativeLibraryLoader.loadFirstAvailable(SSL.class.getClassLoader(),
|
||||
libNames.toArray(new String[libNames.size()]));
|
||||
|
@ -26,11 +26,13 @@
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/tcp.h> // TCP_NOTSENT_LOWAT is a linux specific define
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#include "netty_epoll_linuxsocket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
// TCP_FASTOPEN is defined in linux 3.7. We define this here so older kernels can compile.
|
||||
#ifndef TCP_FASTOPEN
|
||||
@ -349,7 +351,7 @@ jint netty_epoll_linuxsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix)
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_epoll_linuxsocket_JNI_OnUnLoad(JNIEnv* env) {
|
||||
|
@ -36,12 +36,14 @@
|
||||
#include <inttypes.h>
|
||||
#include <link.h>
|
||||
#include <time.h>
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_util.h"
|
||||
#include "netty_unix_limits.h"
|
||||
|
||||
#include "netty_epoll_linuxsocket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_limits.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
// TCP_FASTOPEN is defined in linux 3.7. We define this here so older kernels can compile.
|
||||
#ifndef TCP_FASTOPEN
|
||||
@ -575,7 +577,7 @@ static jint netty_epoll_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefix
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
static void netty_epoll_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
@ -586,12 +588,14 @@ static void netty_epoll_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
netty_epoll_linuxsocket_JNI_OnUnLoad(env);
|
||||
}
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
// Invoked by the JVM when statically linked
|
||||
jint JNI_OnLoad_netty_transport_native_epoll(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, NETTY_JNI_VERSION) != JNI_OK) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
char* packagePrefix = NULL;
|
||||
#ifndef NETTY_NOT_DYNAMIC
|
||||
Dl_info dlinfo;
|
||||
jint status = 0;
|
||||
// We need to use an address of a function that is uniquely part of this library, so choose a static
|
||||
@ -600,12 +604,12 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
fprintf(stderr, "FATAL: transport-native-epoll JNI call to dladdr failed!\n");
|
||||
return JNI_ERR;
|
||||
}
|
||||
char* packagePrefix = netty_unix_util_parse_package_prefix(dlinfo.dli_fname, "netty-transport-native-epoll", &status);
|
||||
packagePrefix = netty_unix_util_parse_package_prefix(dlinfo.dli_fname, "netty-transport-native-epoll", &status);
|
||||
if (status == JNI_ERR) {
|
||||
fprintf(stderr, "FATAL: transport-native-epoll JNI encountered unexpected dlinfo.dli_fname: %s\n", dlinfo.dli_fname);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
#endif /* NETTY_NOT_DYNAMIC */
|
||||
jint ret = netty_epoll_native_JNI_OnLoad(env, packagePrefix);
|
||||
|
||||
if (packagePrefix != NULL) {
|
||||
@ -616,11 +620,20 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return JNI_OnLoad_netty_transport_native_epoll(vm, reserved);
|
||||
}
|
||||
|
||||
// Invoked by the JVM when statically linked
|
||||
void JNI_OnUnload_netty_transport_native_epoll(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, NETTY_JNI_VERSION) != JNI_OK) {
|
||||
// Something is wrong but nothing we can do about this :(
|
||||
return;
|
||||
}
|
||||
netty_epoll_native_JNI_OnUnLoad(env);
|
||||
}
|
||||
|
||||
void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||
JNI_OnUnload_netty_transport_native_epoll(vm, reserved);
|
||||
}
|
||||
|
@ -188,7 +188,11 @@ public final class Native {
|
||||
if (!name.startsWith("linux")) {
|
||||
throw new IllegalStateException("Only supported on Linux");
|
||||
}
|
||||
NativeLibraryLoader.load("netty-transport-native-epoll", PlatformDependent.getClassLoader(Native.class));
|
||||
String []libraryNames = new String[] {
|
||||
"netty-transport-native-epoll",
|
||||
"netty_transport_native_epoll"
|
||||
};
|
||||
NativeLibraryLoader.loadFirstAvailable(PlatformDependent.getClassLoader(Native.class), libraryNames);
|
||||
}
|
||||
|
||||
private Native() {
|
||||
|
@ -24,11 +24,13 @@
|
||||
#include <sys/ucred.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#include "netty_kqueue_bsdsocket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
// Those are initialized in the init(...) method and cached for performance reasons
|
||||
static jclass stringCls = NULL;
|
||||
@ -288,7 +290,7 @@ jint netty_kqueue_bsdsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_kqueue_bsdsocket_JNI_OnUnLoad(JNIEnv* env) {
|
||||
|
@ -18,9 +18,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#include "netty_unix_util.h"
|
||||
#include "netty_unix_errors.h"
|
||||
|
||||
#include "netty_kqueue_eventarray.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
jfieldID kqueueJniPtrFieldId = NULL;
|
||||
|
||||
@ -117,7 +119,7 @@ jint netty_kqueue_eventarray_JNI_OnLoad(JNIEnv* env, const char* packagePrefix)
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_kqueue_eventarray_JNI_OnUnLoad(JNIEnv* env) {
|
||||
|
@ -25,13 +25,16 @@
|
||||
#include <sys/event.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_util.h"
|
||||
#include "netty_unix_limits.h"
|
||||
|
||||
#include "netty_kqueue_bsdsocket.h"
|
||||
#include "netty_kqueue_eventarray.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_limits.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
|
||||
clockid_t waitClockId = 0; // initialized by netty_unix_util_initialize_wait_clock
|
||||
|
||||
@ -255,7 +258,7 @@ static jint netty_kqueue_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefi
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
static void netty_kqueue_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
@ -267,12 +270,15 @@ static void netty_kqueue_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
netty_kqueue_eventarray_JNI_OnUnLoad(env);
|
||||
}
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
// Invoked by the JVM when statically linked
|
||||
jint JNI_OnLoad_netty_transport_native_kqueue(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, NETTY_JNI_VERSION) != JNI_OK) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
char* packagePrefix = NULL;
|
||||
#ifndef NETTY_NOT_DYNAMIC
|
||||
Dl_info dlinfo;
|
||||
jint status = 0;
|
||||
// We need to use an address of a function that is uniquely part of this library, so choose a static
|
||||
@ -281,12 +287,12 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
fprintf(stderr, "FATAL: transport-native-kqueue JNI call to dladdr failed!\n");
|
||||
return JNI_ERR;
|
||||
}
|
||||
char* packagePrefix = netty_unix_util_parse_package_prefix(dlinfo.dli_fname, "netty-transport-native-kqueue", &status);
|
||||
packagePrefix = netty_unix_util_parse_package_prefix(dlinfo.dli_fname, "netty-transport-native-kqueue", &status);
|
||||
if (status == JNI_ERR) {
|
||||
fprintf(stderr, "FATAL: transport-native-kqueue JNI encountered unexpected dlinfo.dli_fname: %s\n", dlinfo.dli_fname);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
#endif /* NETTY_NOT_DYNAMIC */
|
||||
jint ret = netty_kqueue_native_JNI_OnLoad(env, packagePrefix);
|
||||
|
||||
if (packagePrefix != NULL) {
|
||||
@ -297,11 +303,20 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return JNI_OnLoad_netty_transport_native_kqueue(vm, reserved);
|
||||
}
|
||||
|
||||
// Invoked by the JVM when statically linked
|
||||
void JNI_OnUnload_netty_transport_native_kqueue(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if ((*vm)->GetEnv(vm, (void**) &env, NETTY_JNI_VERSION) != JNI_OK) {
|
||||
// Something is wrong but nothing we can do about this :(
|
||||
return;
|
||||
}
|
||||
netty_kqueue_native_JNI_OnUnLoad(env);
|
||||
}
|
||||
|
||||
void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||
return JNI_OnUnload_netty_transport_native_kqueue(vm, reserved);
|
||||
}
|
||||
|
@ -100,7 +100,11 @@ final class Native {
|
||||
if (!name.startsWith("mac") && !name.contains("bsd") && !name.startsWith("darwin")) {
|
||||
throw new IllegalStateException("Only supported on BSD");
|
||||
}
|
||||
NativeLibraryLoader.load("netty-transport-native-kqueue", PlatformDependent.getClassLoader(Native.class));
|
||||
String []libraryNames = new String[] {
|
||||
"netty-transport-native-kqueue",
|
||||
"netty_transport_native_kqueue"
|
||||
};
|
||||
NativeLibraryLoader.loadFirstAvailable(PlatformDependent.getClassLoader(Native.class), libraryNames);
|
||||
}
|
||||
|
||||
private Native() {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <errno.h>
|
||||
#include <jni.h>
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
static jclass runtimeExceptionClass = NULL;
|
||||
@ -206,7 +207,7 @@ jint netty_unix_errors_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_unix_errors_JNI_OnUnLoad(JNIEnv* env) {
|
||||
|
@ -20,9 +20,10 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "netty_unix_util.h"
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_filedescriptor.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
static jmethodID posId = NULL;
|
||||
static jmethodID limitId = NULL;
|
||||
@ -261,7 +262,7 @@ jint netty_unix_filedescriptor_JNI_OnLoad(JNIEnv* env, const char* packagePrefix
|
||||
}
|
||||
|
||||
free(mem);
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_unix_filedescriptor_JNI_OnUnLoad(JNIEnv* env) { }
|
||||
|
25
transport-native-unix-common/src/main/c/netty_unix_jni.h
Normal file
25
transport-native-unix-common/src/main/c/netty_unix_jni.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
#ifndef NETTY_UNIX_JNI_H_
|
||||
#define NETTY_UNIX_JNI_H_
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#ifndef NETTY_JNI_VERSION
|
||||
#define NETTY_JNI_VERSION JNI_VERSION_1_6
|
||||
#endif
|
||||
|
||||
#endif /* NETTY_UNIX_JNI_H_ */
|
@ -17,6 +17,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_limits.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
@ -75,7 +76,7 @@ jint netty_unix_limits_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_unix_limits_JNI_OnUnLoad(JNIEnv* env) { }
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include "netty_unix_errors.h"
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
@ -974,7 +975,7 @@ jint netty_unix_socket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
free(mem);
|
||||
|
||||
socketType = socket_type(env);
|
||||
return JNI_VERSION_1_6;
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_unix_socket_JNI_OnUnLoad(JNIEnv* env) {
|
||||
|
Loading…
Reference in New Issue
Block a user