diff --git a/fine-j2v8/src/main/java/com/eclipsesource/v8/LibraryLoader.java b/fine-j2v8/src/main/java/com/eclipsesource/v8/LibraryLoader.java index 741b8bd3a..514f18819 100644 --- a/fine-j2v8/src/main/java/com/eclipsesource/v8/LibraryLoader.java +++ b/fine-j2v8/src/main/java/com/eclipsesource/v8/LibraryLoader.java @@ -15,6 +15,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.management.ManagementFactory; public class LibraryLoader { @@ -23,6 +24,8 @@ public class LibraryLoader { static final String SWT_LIB_DIR = ".j2v8"; + static final String MINIMUM_VERSION = "6.2"; + static { DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$ SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$ @@ -30,8 +33,9 @@ public class LibraryLoader { /** * Returns the base-name for the native J2V8 library file. + * * @param withLinuxVendor include/exclude the {vendor} part from the returned filename - *

NOTE: Vendors are only included for linux systems

+ *

NOTE: Vendors are only included for linux systems

* @return The filename string has the following structure: *
{arch}-[vendor]-{operating_system}
*/ @@ -44,10 +48,10 @@ public class LibraryLoader { final String separator = "-"; return - prefix + - (vendor != null ? separator + vendor : "") + - separator + os + - separator + arch; + prefix + + (vendor != null ? separator + vendor : "") + + separator + os + + separator + arch; } public static String computeLibraryFullName(boolean withLinuxVendor) { @@ -94,7 +98,7 @@ public class LibraryLoader { return; String path = null; - + if (tempDirectory != null) { path = tempDirectory; } else { @@ -141,6 +145,7 @@ public class LibraryLoader { FileOutputStream os = null; InputStream is = null; File file = new File(fileName); + String absoluteName = file.getAbsolutePath(); boolean extracted = false; try { if (file.exists()) { @@ -158,7 +163,7 @@ public class LibraryLoader { os.close(); is.close(); chmod("755", fileName); - if (load(fileName, message)) { + if (load(absoluteName, message)) { return true; } } @@ -187,8 +192,52 @@ public class LibraryLoader { return; } try { - Runtime.getRuntime().exec(new String[] { "chmod", permision, path }).waitFor(); //$NON-NLS-1$ + Runtime.getRuntime().exec(new String[]{"chmod", permision, path}).waitFor(); //$NON-NLS-1$ } catch (Throwable e) { } } + + //内核版本windows NT6.2以下存在加载dll之后无法正常退出的问题,注册钩子函数退出时杀掉进程 + static void checkExceptionVersion() { + String version = System.getProperty("os.version"); + if (PlatformDetector.OS.isWindows() && belowMinimumVersion(version)) { + registerExit(); + } + } + + //低于指定版本,6.2以下 + private static boolean belowMinimumVersion(String version) { + return compareVersion(version, MINIMUM_VERSION) < 0; + } + + private static int compareVersion(String version1, String version2) { + String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配,不能用"."; + String[] versionArray2 = version2.split("\\."); + int idx = 0; + int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值 + int diff = 0; + while (idx < minLength + && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//先比较长度 + && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//再比较字符 + ++idx; + } + //如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大; + diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length; + return diff; + } + + //低于指定版本,6.2以下 + private static void registerExit() { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + String name = ManagementFactory.getRuntimeMXBean().getName(); + String pid = name.split("@")[0]; + try { + Runtime.getRuntime().exec("taskkill /F /PID " + pid); + } catch (Exception ignore) { + } + } + }); + } } diff --git a/fine-j2v8/src/main/java/com/eclipsesource/v8/PlatformDetector.java b/fine-j2v8/src/main/java/com/eclipsesource/v8/PlatformDetector.java index 0913c1a69..49cd427d8 100644 --- a/fine-j2v8/src/main/java/com/eclipsesource/v8/PlatformDetector.java +++ b/fine-j2v8/src/main/java/com/eclipsesource/v8/PlatformDetector.java @@ -124,8 +124,9 @@ public class PlatformDetector { if (OS.isAndroid()) { return "google"; } - - throw new UnsatisfiedLinkError("Unsupported vendor: " + getName()); + //如果if条件全部不符合,就会陷入死循环,代码存在风险 + //throw new UnsatisfiedLinkError("Unsupported vendor: " + getName()); + return null; } private static String getLinuxOsReleaseId() { @@ -144,7 +145,9 @@ public class PlatformDetector { return parseLinuxRedhatReleaseFile(file); } - throw new UnsatisfiedLinkError("Unsupported linux vendor: " + getName()); + //linux系统下如果缺失/etc/os-release,/usr/lib/os-release,/etc/redhat-release三个文件,就会和getName方法就会一直互相调用 + //throw new UnsatisfiedLinkError("Unsupported linux vendor: " + getName()); + return null; } private static String parseLinuxOsReleaseFile(final File file) { diff --git a/fine-j2v8/src/main/java/com/eclipsesource/v8/V8.java b/fine-j2v8/src/main/java/com/eclipsesource/v8/V8.java index abaec598c..55b3b49c4 100644 --- a/fine-j2v8/src/main/java/com/eclipsesource/v8/V8.java +++ b/fine-j2v8/src/main/java/com/eclipsesource/v8/V8.java @@ -75,6 +75,7 @@ public class V8 extends V8Object { try { LibraryLoader.loadLibrary(tmpDirectory); nativeLibraryLoaded = true; + LibraryLoader.checkExceptionVersion(); } catch (Error e) { nativeLoadError = e; } catch (Exception e) { diff --git a/fine-j2v8/src/main/java/com/eclipsesource/v8/V8OutOfMemoryError.java b/fine-j2v8/src/main/java/com/eclipsesource/v8/V8OutOfMemoryError.java new file mode 100644 index 000000000..29084a341 --- /dev/null +++ b/fine-j2v8/src/main/java/com/eclipsesource/v8/V8OutOfMemoryError.java @@ -0,0 +1,17 @@ +package com.eclipsesource.v8; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2020-11-26 + */ +public class V8OutOfMemoryError extends V8RuntimeException { + + V8OutOfMemoryError(final String message) { + super(message); + } + + V8OutOfMemoryError() { + super(); + } +}