我有一个工作实现,现在从SWT FAQ中引用。
此方法现在可用作ANT任务:SWTJar
[编辑] SWTJar现已更新为使用Alexey Romanov的解决方案,如上所述。
首先,我构建一个包含所有应用程序类的jar。
接下来,我构建一个jar来包含以下所有内容:JAR文件我刚刚建造的罐子
所有的SWT罐子
类“Jar-In-Jar”类加载器类
一个特殊的装载机类 - 见下文
这是build.xml中的片段。
这个loader类使用jar-in-jar-loader来创建一个ClassLoader,它从两个jar中加载类。正确的SWT罐子
应用程序包装器jar
一旦我们有了这个类加载器,我们就可以使用反射启动实际的应用程序main方法。public class TraceClientLoader
{
public static void main(String[] args) throws Throwable
{
ClassLoader cl = getSWTClassloader();
Thread.currentThread().setContextClassLoader(cl);
try
{
try
{
System.err.println("Launching InTrace UI ...");
Class> c = Class.forName("org.intrace.client.gui.TraceClient", true, cl);
Method main = c.getMethod("main", new Class[]{args.getClass()});
main.invoke((Object)null, new Object[]{args});
}
catch (InvocationTargetException ex)
{
if (ex.getCause() instanceof UnsatisfiedLinkError)
{
System.err.println("Launch failed: (UnsatisfiedLinkError)");
String arch = getArch();
if ("32".equals(arch))
{
System.err.println("Try adding '-d64' to your command line arguments");
}
else if ("64".equals(arch))
{
System.err.println("Try adding '-d32' to your command line arguments");
}
}
else
{
throw ex;
}
}
}
catch (ClassNotFoundException ex)
{
System.err.println("Launch failed: Failed to find main class - org.intrace.client.gui.TraceClient");
}
catch (NoSuchMethodException ex)
{
System.err.println("Launch failed: Failed to find main method");
}
catch (InvocationTargetException ex)
{
Throwable th = ex.getCause();
if ((th.getMessage() != null) &&
th.getMessage().toLowerCase().contains("invalid thread access"))
{
System.err.println("Launch failed: (SWTException: Invalid thread access)");
System.err.println("Try adding '-XstartOnFirstThread' to your command line arguments");
}
else
{
throw th;
}
}
}
private static ClassLoader getSWTClassloader()
{
ClassLoader parent = TraceClientLoader.class.getClassLoader();
URL.setURLStreamHandlerFactory(new RsrcURLStreamHandlerFactory(parent));
String swtFileName = getSwtJarName();
try
{
URL intraceFileUrl = new URL("rsrc:intrace-ui-wrapper.jar");
URL swtFileUrl = new URL("rsrc:" + swtFileName);
System.err.println("Using SWT Jar: " + swtFileName);
ClassLoader cl = new URLClassLoader(new URL[] {intraceFileUrl, swtFileUrl}, parent);
try
{
// Check we can now load the SWT class
Class.forName("org.eclipse.swt.widgets.Layout", true, cl);
}
catch (ClassNotFoundException exx)
{
System.err.println("Launch failed: Failed to load SWT class from jar: " + swtFileName);
throw new RuntimeException(exx);
}
return cl;
}
catch (MalformedURLException exx)
{
throw new RuntimeException(exx);
}
}
private static String getSwtJarName()
{
// Detect OS
String osName = System.getProperty("os.name").toLowerCase();
String swtFileNameOsPart = osName.contains("win") ? "win" : osName .contains("mac") ? "osx" : osName.contains("linux")
|| osName.contains("nix") ? "linux" : "";
if ("".equals(swtFileNameOsPart))
{
throw new RuntimeException("Launch failed: Unknown OS name: " + osName);
}
// Detect 32bit vs 64 bit
String swtFileNameArchPart = getArch();
String swtFileName = "swt-" + swtFileNameOsPart + swtFileNameArchPart + "-3.6.2.jar";
return swtFileName;
}
private static String getArch()
{
// Detect 32bit vs 64 bit
String jvmArch = System.getProperty("os.arch").toLowerCase();
String arch = (jvmArch.contains("64") ? "64" : "32");
return arch;
}}
[编辑]如上所述,对于那些寻找“jar-in-jar类加载器”的人:它包含在Eclipse的JDT(基于Eclipse的Java IDE)中。打开带有归档器的org.eclipse.jdt.ui_ * version_number * .jar,你会在里面找到一个文件jar-in-jar-loader.zip。我将其重命名为jar-in-jar-loader.jar。
intrace-ui.jar - 这是我使用上述过程构建的jar。你应该可以在win32 / 64,linux32 / 64和osx32 / 64中的任何一个上运行这个jar。
[编辑]现在从SWT FAQ中引用此答案。