-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathNativeLoader.java
More file actions
152 lines (139 loc) · 5.24 KB
/
NativeLoader.java
File metadata and controls
152 lines (139 loc) · 5.24 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package org.gmssl;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
/**
* @author yongfei.li
* @email 290836576@qq.com
* @date 2023/09/07
* @description Native lib load util
*/
public class NativeLoader {
/* custom jni library prefix path relative to project resources */
private static final String RESOURCELIB_PREFIXPATH = "lib";
static final String GMSSLJNILIB_NAME = "libgmssljni";
private static final Map<String, Path> loadedLibraries = new HashMap<>();
private static final Properties PROPERTIES = new Properties();
static {
try (InputStream input = NativeLoader.class.getClassLoader().getResourceAsStream("config.properties")) {
if (input == null) {
throw new GmSSLException("can't find config file: config.properties");
}
PROPERTIES.load(input);
} catch (IOException e) {
e.printStackTrace();
throw new GmSSLException("can't load config file: config.properties");
}
}
/**
* load jni lib from resources path,the parameter does not contain the path and suffix.
*
* @param library libraryName
*/
public static void load(String library) {
if (loadedLibraries.containsKey(library)) {
return;
}
Path tempFile = null;
String resourceLibPath = RESOURCELIB_PREFIXPATH + "/" + library + "." + libExtension();
try (InputStream inputStream = NativeLoader.class.getClassLoader().getResourceAsStream(resourceLibPath)) {
tempFile = Files.createTempFile(library, "." + libExtension());
tempFile.toFile().deleteOnExit();
Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
checkReferencedLib();
System.load(tempFile.toAbsolutePath().toString());
loadedLibraries.put(library, tempFile);
}catch (IOException e){
throw new GmSSLException("lib file not found:"+ e.getMessage());
}catch (UnsatisfiedLinkError e){
throw new GmSSLException("Failed to load native library:"+ e.getMessage());
} catch (Exception e) {
throw new GmSSLException("Unable to load lib!");
}finally {
if (null != tempFile) {
tempFile.toFile().delete();
}
}
}
/**
* Get the operating system type.
*
* @return operating system name
*/
static String osType() {
String os = "unknown";
String vmName = System.getProperty("java.vm.name");
if ("dalvik".equalsIgnoreCase(vmName) || "art".equalsIgnoreCase(vmName)) {
os = "android";
}
String osName = System.getProperty("os.name").toLowerCase();
if (osName.startsWith("windows")) {
os = "win";
} else if (osName.startsWith("linux")) {
os = "linux";
} else if (osName.startsWith("mac os x") || osName.startsWith("darwin")) {
os = "osx";
} else {
System.err.println("Unsupported OS: " + osName);
}
return os;
}
/**
* Get the library extension name based on the operating system type.
*
* @return extension name
*/
static String libExtension() {
String osType = osType();
String libExtension = null;
switch (osType) {
case "win":
libExtension = "dll";
break;
case "osx":
libExtension = "dylib";
break;
case "linux":
case "android":
libExtension = "so";
break;
default:
throw new IllegalArgumentException("Unsupported OS type!");
}
return libExtension;
}
/**
* In macOS systems, the execution of library calls relies on loading gmssl.3.dylib from the installed gmssl library,
* in order to correct the @rpath path issue. Alternatively, you can manually execute the command
* "install_name_tool -change @rpath/libgmssl.3.dylib /usr/local/lib/libgmssl.3.dylib xxx/lib/libgmssljni.dylib" to fix the library reference path issue.
* This has already been loaded and manual execution is unnecessary.
*/
private static void checkReferencedLib() {
if ("osx".equals(osType())) {
String macReferencedLib = PROPERTIES.getProperty("macReferencedLib");
if (null != macReferencedLib) {
System.load(macReferencedLib);
Optional<String> optionalStr = Optional.ofNullable(macReferencedLib);
if (optionalStr.isPresent() && !optionalStr.get().isEmpty()) {
File libFile = new File(macReferencedLib);
if (libFile.exists()) {
System.load(macReferencedLib);
}
}
}
}
}
}