Clojure и 64-бит lwjgl (лейн 2)

В 64-разрядной JVM, в Linux, независимо от того, что загружает загружаемая библиотека, пытается загрузить 32-разрядную библиотеку.

Я спрашиваю об этом как clojure и (даже более) java n00b.

Ответы, которые я нашел до сих пор (Использование lwjgl в Leiningen/ Clojure, по-видимому, является наиболее заметным в результатах поиска), похоже, для более старых версий лейн, с проблемами, зависящими от: native-зависимостей или LD_LIBRARY_PATH в project.clj.

Я заново изобретаю колесо и перевод основных учебников jME в clojure как небольшое личное домашнее задание для обучения их обоих. Во всех учебниках и примерах, которые я нашел до сих пор, люди, показывающие, как они это сделали, эта часть кажется "просто работающей".

(Это работало отлично для меня под Windows, если на то пошло).

Я использую lein для создания нового пустого проекта. Я установил зависимости от различных версий библиотек jMonkeyEngine на клоарах. После того, как "lein deps", liblwjgl64.so и libopenal64.so завершатся в корне моей директории проекта.

Когда я пытаюсь выполнить "lein run", он показывает экран заставки обезьяны для настроек, затем он выдает исключение, когда пытается на самом деле запустить, потому что пытается загрузить liblwjgl.so.

Этот файл присутствует в файле target/native/linux и target/native/linux64 (хотя, как ни странно, не под target/native/linux32).

Если я скопирую файл, который он хочет в свой корневой каталог проекта, ошибка изменится на "неправильный класс ELF: ELFCLASS32 (Возможная причина: несоответствие ширины слова архитектуры)", который является другим набором обсуждений, которые Google продолжает давать мне. Решения, упомянутые там, похоже, сводятся к "Переключению на 32-разрядную JVM для работы Minecraft", но я бы скорее понял, что происходит.

Эта проблема очень согласована во всех наборах библиотек зависимостей, которые я мог бы получить в клоарах (до версии 2, во всяком случае... у них были большие проблемы, которые, похоже, не стоили вникать). Набор символов Charles "Just Worked" для меня на окнах.

Лучшая гипотеза, с которой мне удалось придумать, работает в этом направлении:

Я подозреваю, что версия должна быть указана в какой-то момент. http://docs.oracle.com/javase/7/docs/technotes/guides/javaws/developersguide/syntax.html#resources упоминает свойство ресурсов, которое выглядит идеально, но это, похоже, не имеет ничего общего с JNLP. Мне интересно, есть ли файл манифеста, сидящий где-то в .jar, который я не смог найти (здесь, где моя n00bishness вступает в игру... Я действительно не понимаю, что я ищу).

Итак, есть ли у кого-нибудь какие-либо указания о том, где я должен искать или кого я должен спросить? Я не знаю достаточно, чтобы даже знать, куда идти отсюда. Было бы более целесообразно приставать к форумам jMonkeyEngine, # clojure или списку рассылки lwjgl (или тому, что они используют... Я вообще не рассматривал их стороны вещей... не так ли?)

Следующее, что я собираюсь попробовать, это объединить библиотеки jME в мой собственный репозиторий. Это похоже на большую, довольно сложную задачу, которую я решил задать здесь, пока я занимаюсь этим углом.

Я знаю, что это расплывчато, и я извиняюсь за это. Мой google-fu подвел меня. Я был бы признателен за любые предложения, которые могут придумать.

Спасибо заранее!

Ответ 1

Я знаю, что это старый вопрос, но я нашел его, решив работать над проектом Clojure + jMonkeyEngine. Я потратил некоторое время на борьбу с пакетами в клоарах, а затем посмотрел, что потребуется для создания моего собственного пакета maven, и я нашел страницу в wiki jMonkeyEngine, у которой было это серьезное предупреждение:

Обратите внимание, что использование jME3 с maven не рекомендуется и не поддерживается основной командой jME и библиотеками в хранилище maven может устарели!

Позже я обнаружил, что смог успешно получить минимальное приложение JME, поставив свои банки непосредственно в мой проект и включив их в путь к классам с помощью leiningen: config путей ресурсов.

Найдите банки, загрузив SDK JME3, и посмотрите в jmonkeyplatform/jmonkeyplatform/libs. Скопируйте все банки в папку "lib" внутри вашего проекта (да, вы можете удалить банки, которые вы не будете использовать). Затем настройте свой проект lein следующим образом:

(defproject my-jme-project "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :resource-paths ["resources" "lib/*"])

Запустите lein-repl, и следующее должно запустить минимальное приложение JME3:

(import 'com.jme3.app.SimpleApplication)
(def app (proxy [SimpleApplication] [] (simpleInitApp [] nil)))
(.start app)

Ответ 2

Использование собственных библиотек с Java-программами может сначала быть больно, но на самом деле это не так уж сложно.

Прежде всего, ваша ошибка wrong ELF class: ELFCLASS32 означает, что определенная 64-разрядная программа пыталась загрузить 32-разрядную общую библиотеку. Это происходит, очевидно, когда есть 32-битная библиотека с требуемым именем присутствует на пути, где программа ищет библиотеки, но сама программа 64-разрядная. Это почти все для объяснения ошибки.

Теперь о главной части вопроса. Существует действительно несколько способов использования собственных библиотек с Java-приложениями, некоторые из которых включают в себя даже переменные среды. Но IMO самый простой способ - указать системное свойство Java java.library.path, которое предназначено именно для управления родными библиотеками. Это свойство должно указывать на каталог, в котором присутствуют все собственные библиотеки для программы. JVM будет искать в этом каталоге все необходимые общие объекты.

При непосредственном запуске файлов JAR можно указать системные свойства в командной строке, например:

java -Djava.library.path=natives/linux64 -jar yourprogram.jar

Здесь мы указываем путь к библиотекам относительно текущего каталога. Насколько мне известно, это предпочтительный способ установки свойств для автономных приложений, которые обычно запускаются скриптами.

Что касается REPL, возможно, для него можно установить параметры JVM внутри project.clj, например:

(defproject project "version"
  ...
  :jvm-opts ["-Djava.library.path=target/natives/linux64"])

Я не помню, что является рабочим каталогом по умолчанию для REPL, поэтому для этого может потребоваться немного экспериментировать с точным путем, но у вас есть точка.

Прямо сейчас я сам разрабатываю программу lwjgl (хотя и не в Clojure, а в простой Java, используя Maven), и все, что действительно требовалось, - это извлечение родных библиотек из jars (maven-native-plugin делает это) и установить java.library.path для них.

Кстати, похоже, что leiningen поддерживает еще один важный параметр в project.clj, :native-path, который, похоже, позволяет что-то вроде функции maven-native-plugin: он указывает каталог, в который должны быть извлечены все нативные зависимости. Объединение этого с :jvm-opts должно дать вам правильную независимую от платформы REPL:)

Ответ 3

Еще старый вопрос, но у меня такая же проблема, поэтому я смог настроить jME3 на Closure, добавив репозиторий jCenter в файл project.clj:

(defproject example-project "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :repositories [["jcenter" "http://jcenter.bintray.com"]]
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.jmonkeyengine/jme3-core "3.1.0-beta1"]
                 [org.jmonkeyengine/jme3-desktop "3.1.0-beta1"]
                 [org.jmonkeyengine/jme3-lwjgl "3.1.0-beta1"]])