Simplify native library resolution using os-maven-plugin
Motivation: So far, we used a very simple platform string such as linux64 and linux32. However, this is far from perfection because it does not include anything about the CPU architecture. Also, the current build tries to put multiple versions of .so files into a single JAR. This doesn't work very well when we have to ship for many different platforms. Think about shipping .so/.dynlib files for both Linux and Mac OS X. Modification: - Use os-maven-plugin as an extension to determine the current OS and CPU architecture reliable at build time - Use Maven classifier instead of trying to put all shared libraries into a single JAR - NativeLibraryLoader does not guess the OS and bit mode anymore and it always looks for the same location regardless of platform, because the Maven classifier does the job instead. Result: Better scalable native library deployment and retrieval
This commit is contained in:
parent
93fab1d5a3
commit
6c1af9036f
@ -24,8 +24,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to load JNI resources.
|
* Helper class to load JNI resources.
|
||||||
@ -35,7 +33,6 @@ public final class NativeLibraryLoader {
|
|||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(NativeLibraryLoader.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(NativeLibraryLoader.class);
|
||||||
|
|
||||||
private static final Pattern REPLACE = Pattern.compile("\\W+");
|
|
||||||
private static final File WORKDIR;
|
private static final File WORKDIR;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -67,7 +64,7 @@ public final class NativeLibraryLoader {
|
|||||||
*/
|
*/
|
||||||
public static void load(String name, ClassLoader loader) {
|
public static void load(String name, ClassLoader loader) {
|
||||||
String libname = System.mapLibraryName(name);
|
String libname = System.mapLibraryName(name);
|
||||||
String path = "META-INF/native/" + osIdentifier() + PlatformDependent.bitMode() + '/' + libname;
|
String path = "META-INF/native/" + libname;
|
||||||
|
|
||||||
URL url = loader.getResource(path);
|
URL url = loader.getResource(path);
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
@ -128,21 +125,6 @@ public final class NativeLibraryLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String osIdentifier() {
|
|
||||||
String name = SystemPropertyUtil.get("os.name", "unknown").toLowerCase(Locale.US).trim();
|
|
||||||
if (name.startsWith("win")) {
|
|
||||||
return "windows";
|
|
||||||
}
|
|
||||||
if (name.startsWith("mac os x")) {
|
|
||||||
return "osx";
|
|
||||||
}
|
|
||||||
if (name.startsWith("linux")) {
|
|
||||||
return "linux";
|
|
||||||
}
|
|
||||||
|
|
||||||
return REPLACE.matcher(name).replaceAll("_");
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeLibraryLoader() {
|
private NativeLibraryLoader() {
|
||||||
// Utility
|
// Utility
|
||||||
}
|
}
|
||||||
|
13
pom.xml
13
pom.xml
@ -362,6 +362,14 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<extensions>
|
||||||
|
<extension>
|
||||||
|
<groupId>kr.motd.maven</groupId>
|
||||||
|
<artifactId>os-maven-plugin</artifactId>
|
||||||
|
<version>1.1.1</version>
|
||||||
|
</extension>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
@ -805,6 +813,11 @@
|
|||||||
<artifactId>exec-maven-plugin</artifactId>
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
<version>1.2.1</version>
|
<version>1.2.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.fusesource.hawtjni</groupId>
|
||||||
|
<artifactId>maven-hawtjni-plugin</artifactId>
|
||||||
|
<version>1.10</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<!-- Workaround for the 'M2E plugin execution not covered' problem.
|
<!-- Workaround for the 'M2E plugin execution not covered' problem.
|
||||||
See: http://wiki.eclipse.org/M2E_plugin_execution_not_covered -->
|
See: http://wiki.eclipse.org/M2E_plugin_execution_not_covered -->
|
||||||
|
@ -60,39 +60,16 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.fusesource.hawtjni</groupId>
|
<groupId>org.fusesource.hawtjni</groupId>
|
||||||
<artifactId>maven-hawtjni-plugin</artifactId>
|
<artifactId>maven-hawtjni-plugin</artifactId>
|
||||||
<version>1.10</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>build-linux64</id>
|
<id>build-native-lib</id>
|
||||||
<configuration>
|
<configuration>
|
||||||
<name>${project.artifactId}</name>
|
<nativeSourceDirectory>${project.basedir}/src/main/c</nativeSourceDirectory>
|
||||||
<buildDirectory>${project.build.directory}/linux64</buildDirectory>
|
<libDirectory>${project.build.outputDirectory}</libDirectory>
|
||||||
<nativeSourceDirectory>${nativeSourceDirectory}</nativeSourceDirectory>
|
<!-- We use Maven's artifact classifier instead.
|
||||||
<libDirectory>${libDirectory}</libDirectory>
|
This hack will make the hawtjni plugin to put the native library
|
||||||
<configureArgs>
|
under 'META-INF/native' rather than 'META-INF/native/${platform}'. -->
|
||||||
<arg>--with-arch=x86_64</arg>
|
<platform>.</platform>
|
||||||
</configureArgs>
|
|
||||||
<platform>linux64</platform>
|
|
||||||
<forceConfigure>true</forceConfigure>
|
|
||||||
<forceAutogen>true</forceAutogen>
|
|
||||||
</configuration>
|
|
||||||
<goals>
|
|
||||||
<goal>generate</goal>
|
|
||||||
<goal>build</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>compile</phase>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>build-linux32</id>
|
|
||||||
<configuration>
|
|
||||||
<buildDirectory>${project.build.directory}/linux32</buildDirectory>
|
|
||||||
<nativeSourceDirectory>${nativeSourceDirectory}</nativeSourceDirectory>
|
|
||||||
<libDirectory>${libDirectory}</libDirectory>
|
|
||||||
<name>${project.artifactId}</name>
|
|
||||||
<configureArgs>
|
|
||||||
<arg>--with-arch=i386</arg>
|
|
||||||
</configureArgs>
|
|
||||||
<platform>linux32</platform>
|
|
||||||
<forceConfigure>true</forceConfigure>
|
<forceConfigure>true</forceConfigure>
|
||||||
<forceAutogen>true</forceAutogen>
|
<forceAutogen>true</forceAutogen>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -104,10 +81,15 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Because the generated JAR is platform dependent, use the platform as a classifier. -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<classifier>${os.detected.classifier}</classifier>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<properties>
|
|
||||||
<nativeSourceDirectory>${basedir}/src/main/c</nativeSourceDirectory>
|
|
||||||
<libDirectory>${basedir}/target/classes/</libDirectory>
|
|
||||||
</properties>
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
dnl ---------------------------------------------------------------------------
|
|
||||||
dnl Copyright 2014 The Netty Project
|
|
||||||
dnl
|
|
||||||
dnl Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
dnl you may not use this file except in compliance with the License.
|
|
||||||
dnl You may obtain a copy of the License at
|
|
||||||
dnl
|
|
||||||
dnl http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
dnl
|
|
||||||
dnl Unless required by applicable law or agreed to in writing, software
|
|
||||||
dnl distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
dnl See the License for the specific language governing permissions and
|
|
||||||
dnl limitations under the License.
|
|
||||||
dnl ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
AC_DEFUN([CUSTOM_M4_SETUP],
|
|
||||||
[
|
|
||||||
AC_MSG_CHECKING(which arch to build for)
|
|
||||||
AC_ARG_WITH([arch],
|
|
||||||
[AS_HELP_STRING([--with-arch@<:@=ARCH@:>@],
|
|
||||||
[Build for the specified architecture. Pick from: i386, x86_64.])],
|
|
||||||
[
|
|
||||||
AS_IF(test -n "$withval", [
|
|
||||||
ARCH="$withval"
|
|
||||||
AC_MSG_RESULT([yes, archs: $ARCH])
|
|
||||||
])
|
|
||||||
],[
|
|
||||||
ARCH=""
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
])
|
|
||||||
AS_IF(test "$ARCH" = "i386", [
|
|
||||||
FLAGS="-m32"
|
|
||||||
], test "ARCH" = "x86_64", [
|
|
||||||
FLAGS="-m64"
|
|
||||||
], [
|
|
||||||
FLAGS=""
|
|
||||||
])
|
|
||||||
AS_IF(test -n "$FLAGS", [
|
|
||||||
CFLAGS="$FLAGS $CFLAGS"
|
|
||||||
CXXFLAGS="$FLAGS $CXXFLAGS"
|
|
||||||
LDFLAGS="$FLAGS $ARCH $LDFLAGS"
|
|
||||||
AC_SUBST(CFLAGS)
|
|
||||||
AC_SUBST(CXXFLAGS)
|
|
||||||
AC_SUBST(LDFLAGS)
|
|
||||||
])
|
|
||||||
])
|
|
Loading…
Reference in New Issue
Block a user