Я записал Java GUI с помощью SWT. Я упаковываю приложение с помощью скрипта Ant (фрагмент ниже).
<jar destfile="./build/jars/swtgui.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="org.swtgui.MainGui" />
<attribute name="Class-Path" value="." />
</manifest>
<fileset dir="./build/classes" includes="**/*.class" />
<zipfileset excludes="META-INF/*.SF" src="lib/org.eclipse.swt.win32.win32.x86_3.5.2.v3557f.jar" />
</jar>
Это производит единственную банку, которая в Windows I может просто дважды щелкнуть для выполнения моего GUI. Оборотная сторона - то, что я должен был явно упаковать пакет окон SWT в свою банку.
Я хотел бы смочь запустить свое приложение на других платформах (прежде всего, Linux и OS X). Самый простой способ сделать это состоял бы в том, чтобы создать платформу определенные банки, которые упаковали соответствующие файлы SWT в отдельные БАНКИ.
Существует ли лучший способ сделать это? Действительно ли возможно создать единственный JAR, который работал бы на нескольких платформах?
Замените выделенный жирным текст в src="lib/org.eclipse.swt.win32.win32.x86_3.5.2.v3557f.jar" на указанный в linux swt jar-файл
Я столкнулся с той же проблемой. Я еще не пробовал, но планирую включить версии swt.jar
для всех платформ и динамически загружать правильную в начале метода main
.
ОБНОВЛЕНИЕ: Сработало. build.xml
включает все jar-файлы:
<zipfileset dir="/home/aromanov/workspace/foo/lib" includes="swt_linux_gtk_x86.jar"/>
<zipfileset dir="/home/aromanov/workspace/foo/lib" includes="swt_macosx_x86.jar"/>
<zipfileset dir="/home/aromanov/workspace/foo/lib" includes="swt_win32_x86.jar"/>
<zipfileset dir="/home/aromanov/workspace/foo/lib" includes="swt_linux_gtk_x64.jar"/>
<zipfileset dir="/home/aromanov/workspace/foo/lib" includes="swt_macosx_x64.jar"/>
<zipfileset dir="/home/aromanov/workspace/foo/lib" includes="swt_win32_x64.jar"/>
, а мой метод main
начинается с вызова этого:
private void loadSwtJar() {
String osName = System.getProperty("os.name").toLowerCase();
String osArch = System.getProperty("os.arch").toLowerCase();
String swtFileNameOsPart =
osName.contains("win") ? "win32" :
osName.contains("mac") ? "macosx" :
osName.contains("linux") || osName.contains("nix") ? "linux_gtk" :
""; // throw new RuntimeException("Unknown OS name: "+osName)
String swtFileNameArchPart = osArch.contains("64") ? "x64" : "x86";
String swtFileName = "swt_"+swtFileNameOsPart+"_"+swtFileNameArchPart+".jar";
try {
URLClassLoader classLoader = (URLClassLoader) getClass().getClassLoader();
Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addUrlMethod.setAccessible(true);
URL swtFileUrl = new URL("rsrc:"+swtFileName); // I am using Jar-in-Jar class loader which understands this URL; adjust accordingly if you don't
addUrlMethod.invoke(classLoader, swtFileUrl);
}
catch(Exception e) {
throw new RuntimeException("Unable to add the SWT jar to the class path: "+swtFileName, e);
}
}
[EDIT] Для тех, кто ищет «загрузчик классов jar-in-jar»: он включен в Eclipse JDT (Java IDE, построенный на Eclipse). Откройте org.eclipse.jdt.ui_ * номер_версии * .jar
с помощью архиватора, и вы найдете внутри файл jar-in-jar-loader.zip
.