Итак, в основном у меня есть несколько собственных файлов в файле 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, она не открывается, кажется...?
Может ли кто-нибудь посоветовать решение этой...?