2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
14 * Modified by Tuukka Lehtonen - Semantum Oy
15 * - allow extracting native library to designated directory
17 package net.jpountz.util;
19 import java.io.IOException;
20 import java.io.InputStream;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.util.Arrays;
26 /** FOR INTERNAL USE ONLY */
31 // Even on Windows, the default compiler from cpptasks (gcc) uses .so as a shared lib extension
32 WINDOWS("win32", "dll"), LINUX("linux", "so"), MAC("darwin", "dylib"), SOLARIS("solaris", "so");
33 public final String name, libExtension;
35 private OS(String name, String libExtension) {
37 this.libExtension = libExtension;
41 private static String arch() {
42 return System.getProperty("os.arch");
45 private static OS os() {
46 String osName = System.getProperty("os.name");
47 if (osName.contains("Linux")) {
49 } else if (osName.contains("Mac")) {
51 } else if (osName.contains("Windows")) {
53 } else if (osName.contains("Solaris") || osName.contains("SunOS")) {
56 throw new UnsupportedOperationException("Unsupported operating system: "
61 private static String resourceName() {
63 String packagePrefix = Native.class.getPackage().getName().replace('.', '/');
65 return "/" + packagePrefix + "/" + os.name + "/" + arch() + "/liblz4-java." + os.libExtension;
68 private static boolean loaded = false;
69 private static boolean failedToLoad = false;
71 public static synchronized boolean isLoaded() {
75 public static boolean failedToLoad() {
79 public static synchronized void load() {
80 load(NativeParameters.extractionPath);
83 public static synchronized void load(Path extractionPath) {
87 throw new UnsatisfiedLinkError("Native LZ4 dynamic library loading failed already. Not retrying.");
89 String resourceName = resourceName();
90 URL libraryUrl = Native.class.getResource(resourceName);
91 if (libraryUrl == null)
92 throw new UnsupportedOperationException("Unsupported OS/arch, cannot find " + resourceName + ". Please try building from source.");
95 Path tempFile = null, out;
96 boolean extract = true;
99 if (extractionPath == null) {
100 out = tempFile = Files.createTempFile("liblz4-java", "." + os().libExtension);
102 out = extractionPath.resolve("liblz4-java." + os().libExtension);
103 if (Files.exists(out)) {
104 byte[] sourceHash = ChecksumUtil.computeSum(libraryUrl);
105 byte[] targetHash = ChecksumUtil.computeSum(out);
106 extract = !Arrays.equals(sourceHash, targetHash);
110 copy(libraryUrl, out);
111 System.load(out.toString());
114 if (tempFile != null && Files.exists(tempFile)) {
116 Files.deleteIfExists(tempFile);
118 // This probably doesn't work on Windows at all.
119 tempFile.toFile().deleteOnExit();
123 } catch (UnsatisfiedLinkError e) {
126 } catch (IOException e) {
128 throw new ExceptionInInitializerError("Cannot unpack liblz4-java");
132 private static long copy(URL url, Path to) throws IOException {
133 try (InputStream in = url.openStream()) {
134 return Files.copy(in, to);