Как динамически установить java.library.path с помощью java 13+?

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

Может ли кто-нибудь посоветовать решение этой...?


person Kris Kristensen    schedule 17.12.2020    source источник