Ссылки на библиотеки для исполняемого файла Linux

StackOverflow https://stackoverflow.com/questions/2102568

Вопрос

Я написал приложение на Java и успешно скомпилировал его, используя gcj.Это сработало на удивление хорошо, но я столкнулся с препятствием:Я могу запустить исполняемый файл только через сценарий оболочки, потому что мне нужно указать пути к библиотекам.

Библиотеки, которые мне нужны, - это SWT, Xerces и GNU-crypto.

Есть ли способ статически связать библиотеки при компиляции в gcj, или это не очень хорошая идея?В качестве альтернативы, могу ли я указать (относительный) путь к библиотеке при компиляции?

В настоящее время мой сценарий оболочки выглядит следующим образом:

#!/bin/sh
export LD_LIBRARY_PATH=./libs/:$LD_LIBRARY_PATH
exec ./MyJavaApp $*
Это было полезно?

Решение

Идея состоит в том, чтобы сделать статическое поле "sys_paths" нулевым чтобы он строил пути на основе измененного значения.Смотрите пост здесь (Пост # 223 от AjaySingh516) http://forums.sun.com/thread.jspa?messageID=3744346#3744346

Class clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
boolean accessible = field.isAccessible();
if (!accessible)
    field.setAccessible(true);
Object original = field.get(clazz);
// Reset it to null so that whenever "System.loadLibrary" is called, it
// will be reconstructed with the changed value.
field.set(clazz, null);
try {
    // Change the value and load the library.
    System.setProperty("java.library.path", "./libs/");
    System.loadLibrary("mylibapr");
} finally {
    // Revert back the changes.
    field.set(clazz, original);
    field.setAccessible(accessible);
}

.

Системные свойства gcj (См.:Стандартные свойства, поддерживаемые libgcj)

http://gcc.gnu.org/onlinedocs/gcj/System-properties.html

.

Решение №2 :Установите системную переменную окружения во время компиляции

http://linux.die.net/man/1/gcj

Для этого вы должны использовать параметр -Djava.library.path=./libs/ с gcj

Из руководства gcj (ссылка выше):

--main= ИМЯ_КЛАССА

Этот параметр используется при связывании для указания имени класса, "основной" метод которого должен вызываться при запуске результирующего исполняемого файла.

-Имя[=значение]

Этот параметр можно использовать только с "--main".Он определяет системное свойство с именем name и значением value.Если значение не указано, то по умолчанию используется пустая строка. Эти системные свойства инициализируются при запуске программы и могут быть извлечены во время выполнения используя метод "java.lang.System.getProperty". System.getProperty.

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

Также смотрите: http://gcc.gnu.org/wiki/Statically_linking_libgcj?action=show&redirect=Statically+linking+libgcj

Другие советы

Чтобы ответить на первую часть вашего вопроса -

Со справочной страницы gcj:"Статическое связывание libgcj может привести к пропуску существенных частей libgcj.Некоторые части libgcj используют отражение для загрузки классов во время выполнения.Поскольку компоновщик не видит эти ссылки во время создания ссылки, он может опустить классы, на которые ссылаются.Результатом обычно (но не всегда) является "ClassNotFoundException", генерируемое во время выполнения.При использовании этой опции необходимо соблюдать осторожность".

Что касается статического связывания других библиотек, я не уверен.У меня не было причин для этого.

Исполняемые файлы Linux отличаются от Windows.Обычно у вас есть "лаунчер" или что-то подобное, в зависимости от того, какую именно оконную систему вы используете.Вы устанавливаете значок в нем, а не в самом исполняемом файле.Обычно сценарии запуска используются для настройки любой среды, которая вам необходима для запуска исполняемого файла.Опять же, все это зависит от вашей конкретной системы окон рабочего стола.

Почему вы используете AOT?Я бы посоветовал прочитать следующая статья.Одним из недостатков, которые он упоминает для AOTs, является следующее...

Динамические приложения.Классы, которые приложение динамически загружает во время выполнения, могут быть недоступны разработчику приложения.Это могут быть сторонние плагины, динамические прокси и другие классы, генерируемые во время выполнения, и так далее.Таким образом, система времени выполнения должна включать интерпретатор байт-кода Java и / или JIT-компилятор.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top