Мне нужно расширить сборку классов Maven из зависимостей, однако она добавляется как конечный класс.
Мне нужно собрать jar с библиотеками .dll в качестве ресурсов.Код для их загрузки не написан мной и включен в проект как зависимость Maven.У меня проблемы с загрузкой этих библиотек.В IntelliJ я добавил путь к библиотекам .dll в структуру проекта.Когда я запускаю код как класс IntelliJ, все работает.
Проблема начинается, когда я хочу запустить упакованный jar.Я использую Maven-Assembly-плагин.Это работает (все зависимости загружены), однако я все еще не могу загрузить эти библиотеки.
У меня возникла идея перезаписать класс, отвечающий за поиск этих библиотек, самостоятельно, однако они как окончательный класс, и яне может их расширить.
Можно ли изменить его подпись?
Часть класса, ответственная за загрузку библиотек:
public final class Hub {
private static final File TEMP_DIRECTORY_LOCATION = new File(System.getProperty("java.io.tmpdir"));
private long nativeHandle;
private final String applicationIdentifier;
public Hub() {
this("");
}
public Hub(String applicationIdentifier) {
this.applicationIdentifier = applicationIdentifier;
loadJniResources();
initialize(applicationIdentifier);
}
private final void loadJniResources() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("mac")) {
boolean wasLoadSuccessful = loadOSXResourceFromSysPath();
if (!wasLoadSuccessful) {
wasLoadSuccessful = copyAndLoadOSXFromTemp();
if (!wasLoadSuccessful) {
throw new UnsatisfiedLinkError("Could Not Load myo and myo-java libs");
}
}
} else if (osName.contains("win")) {
boolean wasLoadSuccessful = loadX64ResourcesFromSysPath();
if (!wasLoadSuccessful) {
wasLoadSuccessful = loadWin32ResourcesFromSysPath();
if (!wasLoadSuccessful) {
setLibDirectory();
wasLoadSuccessful = copyAndLoadX64FromTemp();
if (!wasLoadSuccessful) {
wasLoadSuccessful = copyAndLoadWin32FromTemp();
if (!wasLoadSuccessful) {
throw new UnsatisfiedLinkError("Could Not Load myo and myo-java libs");
}
}
}
}
} else {
System.err.println("Your Operating System is not supported at this time.");
}
}
private void setLibDirectory() {
try {
System.setProperty("java.library.path", TEMP_DIRECTORY_LOCATION.getAbsolutePath());
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean loadX64ResourcesFromSysPath() throws UnsatisfiedLinkError {
try {
System.loadLibrary("myo64");
System.loadLibrary("JNIJavaMyoLib");
return true;
} catch (UnsatisfiedLinkError e) {
String errorMessage = String.format("Unable to load myo64 from system directories.");
System.err.println(errorMessage);
}
return false;
}
private boolean copyAndLoadX64FromTemp() {
try {
File myo64DllTempFile = new File(TEMP_DIRECTORY_LOCATION, "myo64.dll");
myo64DllTempFile.deleteOnExit();
try (InputStream myo64DllInputStream = this.getClass().getResourceAsStream("/x64/myo64.dll")) {
Files.copy(myo64DllInputStream, myo64DllTempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
File jniJavaMyoLibDllTempFile = new File(TEMP_DIRECTORY_LOCATION, "JNIJavaMyoLib64.dll");
jniJavaMyoLibDllTempFile.deleteOnExit();
try (InputStream jniJavaMyoLibDllInputStream = this.getClass().getResourceAsStream("/x64/JNIJavaMyoLib.dll")) {
Files.copy(jniJavaMyoLibDllInputStream, jniJavaMyoLibDllTempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
System.loadLibrary("myo64");
System.loadLibrary("JNIJavaMyoLib64");
return true;
} catch (UnsatisfiedLinkError e) {
String errorMessage = String.format("Unable to load %s from directory %s.", "myo64.dll", TEMP_DIRECTORY_LOCATION);
System.err.println(errorMessage);
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
Сообщения об ошибках:
Во время первой попытки соединения с устройством:
Unable to load myo64 from system directories.
Unable to load myo32 from system directories.
Во время второй попытки соединения с устройством:
Unable to load myo64 from system directories.
Unable to load myo32 from system directories.
java.nio.file.AccessDeniedException: C:\Users\Anka\AppData\Local \Temp\myo64.dll
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
at sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:108)
at java.nio.file.Files.deleteIfExists(Files.java:1165)
at java.nio.file.Files.copy(Files.java:3004)
at com.thalmic.myo.Hub.copyAndLoadX64FromTemp(Hub.java:184)
at com.thalmic.myo.Hub.loadJniResources(Hub.java:67)
at com.thalmic.myo.Hub.<init>(Hub.java:27)
at pl.pollub.controller.device.DeviceTask$2.call(DeviceTask.java:54)
at pl.pollub.controller.device.DeviceTask$2.call(DeviceTask.java:49)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at pl.pollub.controller.device.DeviceTask$1.call(DeviceTask.java:31)
at pl.pollub.controller.device.DeviceTask$1.call(DeviceTask.java:27)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
Unable to load myo32.dll from directory C:\Users\Anka\AppData\Local\Temp.
java.lang.UnsatisfiedLinkError: C:\Users\Anka\AppData\Local\Temp\myo32.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at com.thalmic.myo.Hub.copyAndLoadWin32FromTemp(Hub.java:222)
at com.thalmic.myo.Hub.loadJniResources(Hub.java:69)
at com.thalmic.myo.Hub.<init>(Hub.java:27)
at pl.pollub.controller.device.DeviceTask$2.call(DeviceTask.java:54)
at pl.pollub.controller.device.DeviceTask$2.call(DeviceTask.java:49)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at pl.pollub.controller.device.DeviceTask$1.call(DeviceTask.java:31)
at pl.pollub.controller.device.DeviceTask$1.call(DeviceTask.java:27)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)