LWJGL 'java.lang.UnsatisfiedLinkError': нет lwjgl в java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: no lwjgl in java.libr
ary.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at org.lwjgl.Sys$1.run(Sys.java:73)
at java.security.AccessController.doPrivileged(Native Method)
at org.lwjgl.Sys.doLoadLibrary(Sys.java:66)
at org.lwjgl.Sys.loadLibrary(Sys.java:95)
at org.lwjgl.Sys.<clinit>(Sys.java:112)
at org.lwjgl.opengl.Display.<clinit>(Display.java:135)
at org.lorana.client.Lorana.<init>(Lorana.java:20)
at org.lorana.client.Lorana.main(Lorana.java:31)
Ошибка все еще сохраняется после того, как я связал все собственные библиотеки с каждой библиотекой, на которую ссылаются, и следовал инструкциям http://ninjacave.com/lwjglwitheclipse
Я также следил за другими вопросами на форуме относительно lwjgl unsatisfiedlinkerrors, но безрезультатно.
Буду очень признателен за помощь, заранее спасибо!
2 ответа
LWJGL использует свои собственные переменные для пути к собственным библиотекам:
System.setProperty("org.lwjgl.librarypath", new File("pathToNatives").getAbsolutePath());
Если вы сохранили файловую структуру из пакета LWJGL, вы можете использовать что-то вроде этого:
switch(LWJGLUtil.getPlatform())
{
case LWJGLUtil.PLATFORM_WINDOWS:
{
JGLLib = new File("./native/windows/");
}
break;
case LWJGLUtil.PLATFORM_LINUX:
{
JGLLib = new File("./native/linux/");
}
break;
case LWJGLUtil.PLATFORM_MACOSX:
{
JGLLib = new File("./native/macosx/");
}
break;
}
System.setProperty("org.lwjgl.librarypath", JGLLib.getAbsolutePath());
Не уверен насчет того, чтобы заставить его работать в Eclipse, НО я столкнулся с похожими проблемами при попытке создать исполняемый JAR.
Все приведенные ниже решения предполагают, что у вас есть собственные библиотеки либо вместе с файлом JAR в том же каталоге, либо в виде встроенных ресурсов в JAR.
Как описывает@Dawnkeeper, вы можете просто использовать системное свойство "org.lwjgl.librarypath", чтобы указать LWJGL, где искать нативные библиотеки.
ИЛИ ЖЕ
Как показывает ваша ошибка, LWJGL проверяет более распространенное системное свойство "java.library.path", чтобы найти нативные библиотеки. Вы можете установить это в командной строке при запуске JAR следующим образом:
java -Djava.library.path=./lib -jar myApplication.jar
Как я уже упоминал выше, я хотел автономный исполняемый файл JAR; Я не хотел, чтобы пользователь запускал файл JAR с аргументами командной строки. Я попытался установить это системное свойство из моего main
метод, но вскоре обнаружил, что вы не можете изменить значение этого системного свойства после инициализации среды выполнения JVM. Вместо этого я закончил тем, что написал следующий код (используя обходной путь, связанный выше), чтобы установить "java.library.path" в моем main
метод:
public static void main(String[] args) {
addLwjglNativesToJavaLibraryPathProperty();
// run code dependent on LWJGL here...
}
private static void addLwjglNativesToJavaLibraryPathProperty() {
String osDir;
if (SystemUtils.IS_OS_WINDOWS) {
osDir = "windows";
} else if (SystemUtils.IS_OS_LINUX) {
osDir = "linux";
} else if (SystemUtils.IS_OS_MAC_OSX) {
osDir = "macosx";
} else if (SystemUtils.IS_OS_SOLARIS) {
osDir = "solaris";
} else {
throw new RuntimeException("Unsupported OS: " + System.getProperty("os.name"));
}
addPathToJavaLibraryPathProperty("lib/natives/" + osDir);
}
// https://stackru.com/q/5419039
private static void addPathToJavaLibraryPathProperty(String propertyValue) {
String propertyName = "java.library.path";
try {
Field field = ClassLoader.class.getDeclaredField("usr_paths");
field.setAccessible(true);
String[] paths = (String[]) field.get(null);
for (String path : paths) {
if (propertyValue.equals(path)) return;
}
String[] tmp = new String[paths.length + 1];
System.arraycopy(paths, 0, tmp, 0, paths.length);
tmp[paths.length] = propertyValue;
field.set(null, tmp);
System.setProperty(propertyName, System.getProperty(propertyName) + File.pathSeparator + propertyValue);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to get permissions to set " + propertyName);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Failed to get field handle to set " + propertyName);
}
}
Ссылка на код: https://code.google.com/p/gwahtzee/source/browse/trunk/src/main/java/com/googlecode/gwahtzee/Application.java