-
Notifications
You must be signed in to change notification settings - Fork 3
/
Loader.java
106 lines (95 loc) · 3.51 KB
/
Loader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package org.mizux.javanative;
import com.sun.jna.Platform;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
import java.util.Objects;
/** Load native libraries needed for using javanative-java.*/
public class Loader {
private static final String RESOURCE_PATH = "javanative-" + Platform.RESOURCE_PREFIX + "/";
/** Try to locate the native libraries directory.*/
private static URI getNativeResourceURI() throws IOException {
ClassLoader loader = Loader.class.getClassLoader();
URL resourceURL = loader.getResource(RESOURCE_PATH);
Objects.requireNonNull(resourceURL,
String.format("Resource %s was not found in ClassLoader %s", RESOURCE_PATH, loader));
URI resourceURI;
try {
resourceURI = resourceURL.toURI();
} catch (URISyntaxException e) {
throw new IOException(e);
}
return resourceURI;
}
@FunctionalInterface
private interface PathConsumer<T extends IOException> {
void accept(Path path) throws T;
}
/** Extract native resources in a temp directory.
* @param resourceURI Native resource location.
* @return The directory path containing all extracted libraries.
*/
private static Path unpackNativeResources(URI resourceURI) throws IOException {
Path tempPath;
tempPath = Files.createTempDirectory("javanative-java");
tempPath.toFile().deleteOnExit();
PathConsumer<?> visitor;
visitor = (Path sourcePath) -> Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path newPath = tempPath.resolve(sourcePath.getParent().relativize(file).toString());
Files.copy(file, newPath);
newPath.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
Path newPath = tempPath.resolve(sourcePath.getParent().relativize(dir).toString());
Files.copy(dir, newPath);
newPath.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
});
FileSystem fs;
try {
fs = FileSystems.newFileSystem(resourceURI, Collections.emptyMap());
} catch (FileSystemAlreadyExistsException e) {
fs = FileSystems.getFileSystem(resourceURI);
if (fs == null) {
throw new IllegalArgumentException();
}
}
Path p = fs.provider().getPath(resourceURI);
visitor.accept(p);
return tempPath;
}
/** Unpack and Load the native libraries needed for using javanative-java.*/
private static boolean loaded = false;
public static synchronized void loadNativeLibraries() {
if (!loaded) {
try {
URI resourceURI = getNativeResourceURI();
Path tempPath = unpackNativeResources(resourceURI);
// Load the native library
System.load(tempPath.resolve(RESOURCE_PATH)
.resolve(System.mapLibraryName("jnijavanative"))
.toAbsolutePath()
.toString());
loaded = true;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}