所以基本上我在一个jar文件中有几个本机文件,我需要动态地提取并添加到类路径/模块路径。本机文件类似于.dll、.pak的语言文件等。因此,默认的system.load/system.loadlibrary将不适用于非dll
那么我们尝试了什么:使用java.lang.reflection usr.paths
变数,似乎是显而易见的方法:
Field userPathsField = ClassLoader.class.getDeclaredField("usr_paths");
userPathsField.setAccessible(true);
String[] paths = (String[]) userPathsField.get(null);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < paths.length; i++) {
if (libraryPath.equals(paths[i])) {
continue;
}
sb.append(paths[i]).append(File.pathSeparatorChar);
}
sb.append(libraryPath);
System.setProperty("java.library.path", sb.toString());
但不幸的是,由于 java.lang.reflect
过滤:https://bugs.openjdk.java.net/browse/jdk-8210522
同一篇文章似乎提出了一个选择 MethodHandle.Lookup
比如:
static {
Module java_base = Field.class.getModule(), unnamed = CefHelper.class.getModule();
//System.out.println("module name: "+unnamed.getName());
java_base.addOpens("java.lang.reflect", unnamed);
java_base.addOpens("java.util", unnamed);
try {
var lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
String[] paths = (String[])lookup.findVarHandle(Field.class, "usr_paths", String[].class).get();
//for loop goes here to add the paths to StringBuilder...
} catch (IllegalAccessException | NoSuchFieldException ex) {
throw new RuntimeException(ex);
}
}
但仍然不是香草,因为即使我显式地将其放入静态块(如上图所示)或将其添加到pom.xml中:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--add-opens</arg><arg>java.base/java.lang=ALL-UNNAMED </arg>
<arg>--add-opens</arg><arg>java.base/java.lang.reflect=ALL-UNNAMED</arg>
<arg>--add-opens</arg><arg>java.base/java.io=ALL-UNNAMED</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.3</version>
<configuration>
<mainClass>foo.bar.App</mainClass>
<options>
<option>--add-opens</option><option>java.base/java.lang=ALL-UNNAMED</option>
<option>--add-opens</option><option>java.base/java.lang.reflect=ALL-UNNAMED</option>
<option>--add-opens</option><option>java.base/java.io=ALL-UNNAMED</option>
</options>
</configuration>
</plugin>
</plugins>
</build>
它仍然不允许我获取usr.paths,因此我可以将我的本机路径添加到已经存在的路径中。
例外情况:
Caused by: java.lang.IllegalCallerException: java.lang.reflect is not open to module foo.bar.xxx
at java.base/java.lang.Module.addOpens(Module.java:762)
at foo.bar.ReflectionHelper.<clinit>(ReflectionHelper.java:22)
... 19 more
所以即使我添加addopens部分,它也不会打开它看起来。。。?
有人能给我出个解决办法吗。。。?
暂无答案!
目前还没有任何答案,快来回答吧!