Skip to content

Commit

Permalink
fix:Optimize NativeLoader to Prevent Duplicate Loading and Handle Exc…
Browse files Browse the repository at this point in the history
…eptions
  • Loading branch information
liyongfei committed Sep 26, 2024
1 parent 2f1adfa commit 1d27b02
Showing 1 changed file with 71 additions and 49 deletions.
120 changes: 71 additions & 49 deletions src/main/java/org/gmssl/NativeLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;

Expand All @@ -26,7 +29,9 @@ 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";
static final String GMSSLJNILIB_NAME = "libgmssljni";

private static final Map<String, Path> loadedLibraries = new HashMap<>();

private static final Properties PROPERTIES = new Properties();

Expand All @@ -44,64 +49,80 @@ public class NativeLoader {

/**
* load jni lib from resources path,the parameter does not contain the path and suffix.
* @param libaray libarayName
*
* @param library libraryName
*/
public synchronized static void load (String libaray){
String resourceLibPath = RESOURCELIB_PREFIXPATH + "/" + libaray + "." + libExtension();
public static void load(String library) {
if (loadedLibraries.containsKey(library)) {
return;
}
Path tempFile = null;
String resourceLibPath = Paths.get(RESOURCELIB_PREFIXPATH, library + "." + libExtension()).toString();
try (InputStream inputStream = NativeLoader.class.getClassLoader().getResourceAsStream(resourceLibPath)) {
if (null == inputStream) {
throw new GmSSLException("lib file not found in JAR: " + resourceLibPath);
}
Path tempFile = Files.createTempFile(libaray, "."+libExtension());
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 from JAR");
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 osName = System.getProperty("os.name").toLowerCase();
if(osName.startsWith("windows")){
os="win";
}
if(osName.startsWith("linux")){
if ("dalvik".equalsIgnoreCase(System.getProperty("java.vm.name"))) {
os = "android";
System.setProperty("jna.nounpack", "true");
} else {
os="linux";
}
static String osType() {
String os = "unknown";
String vmName = System.getProperty("java.vm.name");
if ("dalvik".equalsIgnoreCase(vmName) || "art".equalsIgnoreCase(vmName)) {
os = "android";
}
if(osName.startsWith("mac os x") || osName.startsWith("darwin")){
os="osx";
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;
if("win".equals(osType)){
libExtension="dll";
}
if("osx".equals(osType)){
libExtension="dylib";
}
if("linux".equals(osType)){
libExtension="so";
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;
}
Expand All @@ -112,20 +133,21 @@ static String libExtension(){
* 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");
Optional<String> optionalStr = Optional.ofNullable(macReferencedLib);
if(optionalStr.isPresent() && !optionalStr.get().isEmpty()){
File libFile = new File(macReferencedLib);
if(libFile.exists()){
System.load(macReferencedLib);
}
}

}
}
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);
}
}
}
}
}

}

0 comments on commit 1d27b02

Please sign in to comment.