Как я могу создать исполняемый файл JAR с SWT, который работает на всех платформах?

SWT поставляется с базовым JAR и одним конкретным JAR для каждой платформы (Windows, Linux / 32-битная, Linux / 64-битная, Mac, AIX, ...). Как я могу создать исполняемый файл JAR, который будет выбирать JAR правильной платформы во время выполнения?

[РЕДАКТИРОВАТЬ] Я думал разместить все JAR-файлы платформы в подкаталоге, а в main() затем изменить загрузчик классов. Кто-нибудь уже пробовал это?


person Aaron Digulla    schedule 10.01.2010    source источник
comment
Почему бы вам не распространить несколько исполняемых файлов для каждой платформы (как Eclipse)?   -  person Pascal Thivent    schedule 11.01.2010
comment
Потому что SWT занимает лишь небольшую часть приложения: в настоящее время все это занимает 30 МБ. Поэтому я могу либо попросить людей загрузить 32 МБ для каждой платформы, либо загрузить один файл размером 40 МБ (для шести платформ), который работает повсюду.   -  person Aaron Digulla    schedule 11.01.2010
comment
В случае с eclipse у нас есть 10+ загрузок, каждая ›100 МБ, и единственное различие между ними - это SWT jar. Мне нужна либо одна загрузка, либо одна большая основная загрузка и небольшая загрузка для каждой платформы, которая загружается автоматически, когда я запускаю приложение в первый раз.   -  person Aaron Digulla    schedule 11.01.2010
comment
То, что вы описываете, является больше проблемой для поставщика приложения, чем для пользователей. Как пользователь, я предпочитаю загружать файл exec. Но я понял, что ты не хочешь этого делать :)   -  person Pascal Thivent    schedule 12.01.2010
comment
Я хочу, чтобы установка была менее болезненной для пользователя. Я хочу дать им один файл, который работает на любой поддерживаемой платформе. Если они хотят перенести приложение на следующий компьютер / ОС (например, 64-битную Windows или новый Linux), должно быть возможно просто скопировать приложение и покончить с этим.   -  person Aaron Digulla    schedule 12.01.2010


Ответы (5)


Посмотрите на это, есть образец кода: Создать кроссплатформенное приложение java swt

person Tute    schedule 23.07.2010

Для моей текущей работы мне нужно было предоставить исполняемый jar-файл, который мог бы загружать jar-файлы внутри себя и выполнять второй main (). В основном это bootstrap main () и приложение main ().

Шаг 1. в манифесте "main-class" вы помещаете свой класс начальной загрузки.

Шаг 2. Когда ваш класс начальной загрузки запускает, он отключает собственный jar-файл и все jar-файлы внутри него во временный каталог. Используйте что-то вроде строки ниже, чтобы получить собственную банку.

Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()

Шаг 3. Класс начальной загрузки определяет ОС через свойство «os.name» и загружает соответствующие jar-файлы из временного каталога с этим

private static void loadJarIntoClassloader( URL u ) throws Exception
{
    URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

    Class<URLClassLoader> sysclass = URLClassLoader.class;
    Method method = sysclass.getDeclaredMethod("addURL", URL.class);
    method.setAccessible(true);
    method.invoke(sysLoader, new Object[]{u});
}

Шаг 4. Теперь вы можете запустить свое приложение, вызвав приложение main ().

ПРИМЕЧАНИЕ. Этот небольшой прием зависит от вашей JVM, использующей URLClassLoader в качестве SystemClassLoader, что верно для JVM Sun, а не для других.

Таким образом, вы можете доставить только одну банку, и она сама распакуется и запустится с правильными банками.

person karoberts    schedule 11.01.2010
comment
Если вы хотите быть независимым от типа загрузчика классов, просто используйте метод factory newInstance(urls, parentClassLoader), чтобы обернуть его, а затем установите новый загрузчик классов с помощью Thread.currentThread().setContextClassLoader (). - person Aaron Digulla; 11.01.2010
comment
+1 Интересная идея создать путь к классам в одном main, а затем вызвать другой. - person Aaron Digulla; 11.01.2010

IIUC, у вас все еще будет проблема с указанием библиотеки JNI для конкретной платформы. Возможно, вы сможете использовать Java Web Start для этого, но я не пробовал. В качестве альтернативы некоторые проекты создают собственные установщики для поддерживаемых платформ. Например, Развертывание приложений SWT в Mac OS X описывает, как для создания пакета приложений SWT для Mac. Такой подход используется в этом примере. Я также видел, как использовалась эта JarBundler Ant Task.

Приложение: статья Развертывание приложения SWT на Java Webstart включает несколько полезных ссылок.

person trashgod    schedule 10.01.2010
comment
Я пробовал использовать URLClassLoader, но возникли две проблемы: если JAR не указан в ClassPath в MANIFEST.MF, загрузка DLL завершится ошибкой. Это означает, что я должен добавить все файлы JAR SWT в путь к классам одновременно. Это приводит к проблеме, заключающейся в том, что 32-битные и 64-битные библиотеки DLL видны, и загрузка любой из них завершится ошибкой. вздох В конце я добавлю все JAR в путь к классу, но скопирую только один SWT JAR в каталог lib. Таким образом будет загружен только один JAR. - person Aaron Digulla; 11.01.2010
comment
Я вижу техническую привлекательность, но также вижу трудности с обслуживанием. Столкнувшись с аналогичной проблемой, я добавил ссылку на статью SO, в которой упоминается JWS. - person trashgod; 11.01.2010

Возможно, http://one-jar.sourceforge.net/ (плагин Maven по адресу http://code.google.com/p/onejar-maven-plugin/) может помочь в этом направлении ...

person Marcel Stör    schedule 10.01.2010

Будет проще использовать разные сценарии оболочки для разных платформ и указать в сценарии jar, зависящий от платформы.

person Denis Tulskiy    schedule 10.01.2010
comment
Я мог писать сценарии оболочки, но я действительно надеялся избежать этого. Мое текущее решение (добавить все SWT JAR в путь к классам, но скопировать только правильный в каталог lib) работает. Осталось написать установщик :) - person Aaron Digulla; 11.01.2010