Change loading of native libraries. They are now included in the
classpath and extracted to a temporary directory during runtime. Looks like I also fixed the loading problems of libusb.dylib on MacOS X by changing the dependency path from @executable_path to @loader_path. So no java.library.path and DYLD_LIBRARY_PATH needed anymore. Just add usb4java as a dependency and that#s it.
This commit is contained in:
parent
7affcc1864
commit
e7948fc191
24
pom.xml
24
pom.xml
@ -113,30 +113,6 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2.1</version><!--$NO-MVN-MAN-VER$-->
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/src.xml</descriptor>
|
||||
<descriptor>src/main/assembly/linux-x86.xml</descriptor>
|
||||
<descriptor>src/main/assembly/linux-x86_64.xml</descriptor>
|
||||
<descriptor>src/main/assembly/windows-x86.xml</descriptor>
|
||||
<descriptor>src/main/assembly/windows-x86_64.xml</descriptor>
|
||||
<descriptor>src/main/assembly/macosx-universal.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>package-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>attached</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
<assembly>
|
||||
<id>linux-x86</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/assembly/linux-x86</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<fileMode>644</fileMode>
|
||||
<lineEnding>keep</lineEnding>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -1,18 +0,0 @@
|
||||
<assembly>
|
||||
<id>linux-x86_64</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/assembly/linux-x86_64</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<fileMode>644</fileMode>
|
||||
<lineEnding>keep</lineEnding>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -1,18 +0,0 @@
|
||||
<assembly>
|
||||
<id>macosx-universal</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/assembly/macosx-universal</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<fileMode>644</fileMode>
|
||||
<lineEnding>keep</lineEnding>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -1,24 +0,0 @@
|
||||
<assembly>
|
||||
<id>src</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
<format>tar.bz2</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<includes>
|
||||
<include>README.txt</include>
|
||||
<include>LICENSE.txt</include>
|
||||
<include>pom.xml</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src</directory>
|
||||
<excludes>
|
||||
<exclude>**/log?????.txt</exclude>
|
||||
<exclude>**/dump/out/*</exclude>
|
||||
<exclude>**/dump/lib/*.class</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -1,18 +0,0 @@
|
||||
<assembly>
|
||||
<id>windows-x86</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/assembly/windows-x86</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<fileMode>644</fileMode>
|
||||
<lineEnding>keep</lineEnding>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -1,18 +0,0 @@
|
||||
<assembly>
|
||||
<id>windows-x86_64</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/assembly/windows-x86_64</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<fileMode>644</fileMode>
|
||||
<lineEnding>keep</lineEnding>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -10,7 +10,7 @@ cd $(dirname $0)/..
|
||||
OS=linux
|
||||
ARCH=x86
|
||||
TMPDIR=$(pwd)/tmp
|
||||
DISTDIR=$(pwd)/../assembly/${OS}-${ARCH}
|
||||
DISTDIR=$(pwd)/../resources/${OS}-${ARCH}
|
||||
|
||||
# Clean up
|
||||
rm -rf $TMPDIR
|
||||
|
||||
@ -9,7 +9,7 @@ cd $(dirname $0)/..
|
||||
OS=linux
|
||||
ARCH=x86_64
|
||||
TMPDIR=$(pwd)/tmp
|
||||
DISTDIR=$(pwd)/../assembly/${OS}-${ARCH}
|
||||
DISTDIR=$(pwd)/../resources/${OS}-${ARCH}
|
||||
|
||||
# Clean up
|
||||
rm -rf $TMPDIR
|
||||
|
||||
@ -8,7 +8,7 @@ cd $(dirname $0)/..
|
||||
OS=macosx
|
||||
ARCH=universal
|
||||
TMPDIR=$(pwd)/tmp
|
||||
DISTDIR=$(pwd)/../assembly/${OS}-${ARCH}
|
||||
DISTDIR=$(pwd)/../resources/${OS}-${ARCH}
|
||||
|
||||
# Clean up
|
||||
rm -rf $TMPDIR
|
||||
@ -66,4 +66,4 @@ rm -rf $TMPDIR
|
||||
# Remove paths from libraries
|
||||
install_name_tool -id @executable_path/libusb.dylib $DISTDIR/libusb.dylib
|
||||
install_name_tool -id @executable_path/libusb4java.dylib $DISTDIR/libusb4java.dylib
|
||||
install_name_tool -change /usr/lib/libusb-0.1.4.dylib @executable_path/libusb.dylib $DISTDIR/libusb4java.dylib
|
||||
install_name_tool -change /usr/lib/libusb-0.1.4.dylib @loader_path/libusb.dylib $DISTDIR/libusb4java.dylib
|
||||
|
||||
@ -9,7 +9,7 @@ cd $(dirname $0)/..
|
||||
OS=windows
|
||||
ARCH=x86
|
||||
TMPDIR=$(pwd)/tmp
|
||||
DISTDIR=$(pwd)/../assembly/${OS}-${ARCH}
|
||||
DISTDIR=$(pwd)/../resources/${OS}-${ARCH}
|
||||
|
||||
# Clean up
|
||||
rm -rf $TMPDIR
|
||||
|
||||
@ -9,7 +9,7 @@ cd $(dirname $0)/..
|
||||
OS=windows
|
||||
ARCH=x86_64
|
||||
TMPDIR=$(pwd)/tmp
|
||||
DISTDIR=$(pwd)/../assembly/${OS}-${ARCH}
|
||||
DISTDIR=$(pwd)/../resources/${OS}-${ARCH}
|
||||
|
||||
# Clean up
|
||||
rm -rf $TMPDIR
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||
* See LICENSE.txt for licensing information.
|
||||
*/
|
||||
|
||||
package de.ailis.usb4java.exceptions;
|
||||
|
||||
/**
|
||||
* Exception thrown when something goes wrong while loading native libraries.
|
||||
*
|
||||
* @author Klaus Reimer (k@ailis.de)
|
||||
*/
|
||||
public final class NativesException extends RuntimeException
|
||||
{
|
||||
/** Serial version UID. */
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param message
|
||||
* The error message.
|
||||
*/
|
||||
public NativesException(final String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param message
|
||||
* The error message.
|
||||
* @param cause
|
||||
* The root cause.
|
||||
*/
|
||||
public NativesException(final String message, final Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
216
src/main/java/de/ailis/usb4java/jni/NativesLoader.java
Normal file
216
src/main/java/de/ailis/usb4java/jni/NativesLoader.java
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||
* See LICENSE.txt for licensing information.
|
||||
*/
|
||||
|
||||
package de.ailis.usb4java.jni;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import de.ailis.usb4java.exceptions.NativesException;
|
||||
import de.ailis.usb4java.support.IOUtils;
|
||||
|
||||
/**
|
||||
* Utility class to load native libraries from classpath.
|
||||
*
|
||||
* @author Klaus Reimer (k@ailis.de)
|
||||
*/
|
||||
public final class NativesLoader
|
||||
{
|
||||
/** If Windows operating system. */
|
||||
private static final boolean WINDOWS = System.getProperty("os.name")
|
||||
.contains("Windows");
|
||||
|
||||
/** If Linux operating system. */
|
||||
private static final boolean LINUX = System.getProperty("os.name")
|
||||
.contains("Linux");
|
||||
|
||||
/** If Mac operating system. */
|
||||
private static final boolean MAC = System.getProperty("os.name").contains(
|
||||
"Mac");
|
||||
|
||||
/** If 64 bit operating system. */
|
||||
private static final boolean IS_64_BIT = System.getProperty("os.arch")
|
||||
.equals("amd64") ||
|
||||
System.getProperty("os.arch").equals("x86_64");
|
||||
|
||||
/** The temporary directory for native libraries. */
|
||||
private static final File TMP = createTempDirectory();
|
||||
|
||||
/** If library is already loaded. */
|
||||
private static boolean loaded = false;
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private NativesLoader()
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the temporary directory used for unpacking the native libraries.
|
||||
* This directory is marked for deletion on exit.
|
||||
*
|
||||
* @return The temporary directory for native libraries.
|
||||
*/
|
||||
private static File createTempDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
File tmp = File.createTempFile("usb4java", null);
|
||||
tmp.delete();
|
||||
tmp.mkdirs();
|
||||
tmp.deleteOnExit();
|
||||
return tmp;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new NativesException("Unable to create temporary directory " +
|
||||
"for usb4java natives: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the platform name. This could be for example "linux-x86" or
|
||||
* "windows-x86_64".
|
||||
*
|
||||
* @return The architecture name. Never null.
|
||||
* @throws NativesException
|
||||
* When operating system or architecture is not supported.
|
||||
*/
|
||||
private static String getPlatform()
|
||||
{
|
||||
if (WINDOWS)
|
||||
return IS_64_BIT ? "windows-x86_64" : "windows-x86";
|
||||
else if (MAC)
|
||||
return "macosx-universal";
|
||||
else if (LINUX)
|
||||
return IS_64_BIT ? "linux-x86_64" : "linux-x86";
|
||||
else
|
||||
throw new NativesException("Unsupported operating system ("
|
||||
+ System.getProperty("os.name") + ") and/or architecture ("
|
||||
+ System.getProperty("os.arch") + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the usb4java native library. This could be
|
||||
* "libusb4java.dll" for example.
|
||||
*
|
||||
* @return The usb4java native library name. Never null.
|
||||
* @throws NativesException
|
||||
* When operating system or architecture is not supported.
|
||||
*/
|
||||
private static String getLibName()
|
||||
{
|
||||
if (WINDOWS)
|
||||
return "libusb4java.dll";
|
||||
else if (MAC)
|
||||
return "libusb4java.dylib";
|
||||
else if (LINUX)
|
||||
return "libusb4java.so";
|
||||
else
|
||||
throw new NativesException("Unsupported operating system ("
|
||||
+ System.getProperty("os.name") + ") and/or architecture ("
|
||||
+ System.getProperty("os.arch") + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the libusb native library. This could be
|
||||
* "libusb0.dll" for example or null if this library is not needed on the
|
||||
* current platform (Because it is provided by the operating system).
|
||||
*
|
||||
* @return The libusb native library name or null if not needed.
|
||||
* @throws NativesException
|
||||
* When operating system or architecture is not supported.
|
||||
*/
|
||||
private static String getExtraLibName()
|
||||
{
|
||||
if (WINDOWS)
|
||||
return "libusb0.dll";
|
||||
else if (MAC)
|
||||
return "libusb.dylib";
|
||||
else if (LINUX)
|
||||
return null;
|
||||
else
|
||||
throw new NativesException("Unsupported operating system ("
|
||||
+ System.getProperty("os.name") + ") and/or architecture ("
|
||||
+ System.getProperty("os.arch") + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a single library.
|
||||
*
|
||||
* @param platform
|
||||
* The platform name (For example "linux-x86")
|
||||
* @param lib
|
||||
* The library name to extract (For example "libusb0.dll")
|
||||
* @return The absolute path to the extracted library.
|
||||
*/
|
||||
private static String extractLibrary(String platform, String lib)
|
||||
{
|
||||
// Extract the usb4java library
|
||||
final String source = platform + "/" + lib;
|
||||
final File dest = new File(TMP, lib);
|
||||
try
|
||||
{
|
||||
final InputStream stream =
|
||||
NativesLoader.class.getClassLoader()
|
||||
.getResourceAsStream(source);
|
||||
if (stream == null)
|
||||
throw new NativesException("Unable to find " + source
|
||||
+ " in the classpath");
|
||||
try
|
||||
{
|
||||
IOUtils.copy(stream, dest);
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new NativesException(
|
||||
"Unable to extract native library " + source + " to " + dest
|
||||
+ ": " + e, e);
|
||||
}
|
||||
|
||||
// Mark usb4java library for deletion
|
||||
dest.deleteOnExit();
|
||||
|
||||
return dest.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the usb4java library (and the libusb library if needed) and
|
||||
* returns the absolute filename to be loaded by Java. The extracted
|
||||
* libraries are marked for deletion on exit.
|
||||
*
|
||||
* @return The absolute path to the extracted usb4java library.
|
||||
*/
|
||||
private static String extract()
|
||||
{
|
||||
final String platform, lib, extraLib;
|
||||
|
||||
platform = getPlatform();
|
||||
lib = getLibName();
|
||||
extraLib = getExtraLibName();
|
||||
if (extraLib != null) extractLibrary(platform, extraLib);
|
||||
return extractLibrary(platform, lib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the usb4java native library. Can be safely called multiple times.
|
||||
* Duplicate calls are ignored.
|
||||
*/
|
||||
public static void load()
|
||||
{
|
||||
if (loaded) return;
|
||||
final String path = extract();
|
||||
System.load(path);
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@ -5,12 +5,8 @@
|
||||
|
||||
package de.ailis.usb4java.jni;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
@ -224,37 +220,9 @@ public final class USB
|
||||
/** Endpoint interrupt type. */
|
||||
public static final int USB_ENDPOINT_TYPE_INTERRUPT = 3;
|
||||
|
||||
/** Possible library names we try to load. */
|
||||
private static String[] libNames = new String[] { "usb4java", "usb4java32",
|
||||
"libusb4java", "libusb4java32" };
|
||||
|
||||
static
|
||||
{
|
||||
final List<Throwable> errors = new ArrayList<Throwable>();
|
||||
for (final String libName : libNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.loadLibrary(libName);
|
||||
errors.clear();
|
||||
break;
|
||||
}
|
||||
catch (final Throwable e)
|
||||
{
|
||||
errors.add(e);
|
||||
}
|
||||
}
|
||||
if (!errors.isEmpty())
|
||||
{
|
||||
final StringWriter out = new StringWriter();
|
||||
for (final Throwable error: errors)
|
||||
{
|
||||
error.printStackTrace(new PrintWriter(out));
|
||||
}
|
||||
LOG.severe(out.toString());
|
||||
throw new RuntimeException(
|
||||
"Unable to load JNI library of usb4java");
|
||||
}
|
||||
NativesLoader.load();
|
||||
}
|
||||
|
||||
|
||||
|
||||
73
src/main/java/de/ailis/usb4java/support/IOUtils.java
Normal file
73
src/main/java/de/ailis/usb4java/support/IOUtils.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Klaus Reimer <k@ailis.de>
|
||||
* See LICENSE.txt for licensing information.
|
||||
*/
|
||||
|
||||
package de.ailis.usb4java.support;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* IO utility methods.
|
||||
*
|
||||
* @author Klaus Reimer (k@ailis.de)
|
||||
*/
|
||||
public final class IOUtils
|
||||
{
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private IOUtils()
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the specified input stream to the specified output stream.
|
||||
*
|
||||
* @param input
|
||||
* The input stream.
|
||||
* @param output
|
||||
* The output stream.
|
||||
* @throws IOException
|
||||
* If copying failed.
|
||||
*/
|
||||
public static void copy(final InputStream input, final OutputStream output)
|
||||
throws IOException
|
||||
{
|
||||
final byte[] buffer = new byte[8192];
|
||||
int read;
|
||||
while ((read = input.read(buffer)) != -1)
|
||||
{
|
||||
output.write(buffer, 0, read);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the specified input stream to the specified output file.
|
||||
*
|
||||
* @param input
|
||||
* The input stream.
|
||||
* @param output
|
||||
* The output file.
|
||||
* @throws IOException
|
||||
* If copying failed.
|
||||
*/
|
||||
public static void copy(final InputStream input, final File output)
|
||||
throws IOException
|
||||
{
|
||||
FileOutputStream stream = new FileOutputStream(output);
|
||||
try
|
||||
{
|
||||
copy(input, stream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user