Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用在所有平台上运行的SWT创建可执行JAR?_Java_Swt_Executable_Portability - Fatal编程技术网

Java 如何使用在所有平台上运行的SWT创建可执行JAR?

Java 如何使用在所有平台上运行的SWT创建可执行JAR?,java,swt,executable,portability,Java,Swt,Executable,Portability,SWT为每个平台(Windows、Linux/32位、Linux/64位、Mac、AIX等)提供了一个基本JAR和一个特定JAR。如何创建一个可执行JAR,在运行时选择正确的平台JAR [EDIT]我想在一个子目录中提供所有平台JAR,然后在main()中修改类加载器。有人试过吗?也许(Maven plugin at)可以在这方面有所帮助……IIUC,您仍然有指定特定于平台的JNI库的问题。你也许可以利用这一点,但我没有试过。或者,一些项目为受支持的平台构建自定义安装程序。例如,描述如何构造SW

SWT为每个平台(Windows、Linux/32位、Linux/64位、Mac、AIX等)提供了一个基本JAR和一个特定JAR。如何创建一个可执行JAR,在运行时选择正确的平台JAR


[EDIT]我想在一个子目录中提供所有平台JAR,然后在
main()
中修改类加载器。有人试过吗?

也许(Maven plugin at)可以在这方面有所帮助……

IIUC,您仍然有指定特定于平台的JNI库的问题。你也许可以利用这一点,但我没有试过。或者,一些项目为受支持的平台构建自定义安装程序。例如,描述如何构造SWT Mac应用程序包。本文采用的是这种方法。我也见过这种用法


附录:本文包含了一些有用的参考资料。

对于不同的平台使用不同的shell脚本并在脚本中指定特定于平台的jar将更容易。

对于我当前的工作,我需要提供一个可执行的jar,它可以在自身内部加载jar并执行第二个main()。基本上是一个引导程序main()和一个应用程序main()

第一步。在清单“主类”中,您将引导类放在

第二步。当引导类运行时,它会将自己的jar和其中的所有jar解压到一个临时目录中。使用类似下面这行的东西来获得你自己的罐子

Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()
第三步。引导类通过“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});
}
private static void loadJarIntoClassloader(URL u)引发异常
{
URLClassLoader sysLoader=(URLClassLoader)ClassLoader.getSystemClassLoader();
类sysclass=URLClassLoader.Class;
方法Method=sysclass.getDeclaredMethod(“addURL”,URL.class);
方法setAccessible(true);
调用(sysLoader,新对象[]{u});
}
第四步。现在,您应该能够通过调用application main()来运行应用程序

注意:这个小技巧依赖于JVM使用
URLClassLoader
作为系统类加载器,这对于Sun JVM是正确的,对于其他JVM则不确定


通过这种方式,您可以只交付一个jar,它将解包并使用正确的jar运行。

看看这个,这里有一个代码示例:

我现在尝试使用URLClassLoader,但有两个问题:如果JAR不在MANIFEST.MF的类路径中,则加载DLL将失败。这意味着我必须同时将所有SWT JAR添加到类路径中。这会导致32位和64位DLL可见的问题,并且加载任一DLL都将失败。最后,我将把所有JAR添加到类路径中,但只将单个SWT JAR复制到lib目录中。这样,只需加载一个罐子。我可以看到技术的吸引力,但我也可以看到维护的困难。面对类似的问题,我在一篇提到JWS的文章中添加了一个链接。我可以编写shell脚本,但我真的希望避免这种情况。我当前的解决方案(将所有SWT JAR添加到类路径中,但只将正确的一个复制到lib目录中)可以工作。现在,我只需要编写一个安装程序:)为什么不为每个平台分发几个可执行文件(一个la Eclipse)?因为SWT只占应用程序的一小部分:整个应用程序目前为30MB。因此,我可以要求人们为每个平台下载32MB,或者下载一个40MB(六个平台)文件,该文件在任何地方都可以运行。在eclipse的情况下,我们有10多个下载,每个都>100MB,它们之间的唯一区别是SWT jar。我想要一个单一的下载,或者一个大的主下载,每个平台一个小的下载,在我第一次运行应用程序时自动下载。你所描述的是应用程序提供商的问题,而不是用户的问题。作为用户,我更喜欢下载32MB的exec。但是我知道你不想这样做:)我想要的是让安装对用户来说不那么痛苦。我想给他们一个在任何受支持的平台上工作的单一文件。如果他们想将应用程序带到下一台计算机/操作系统(例如,64位Windows或新的Linux设备),应该可以只复制应用程序并使用它。如果你想独立于类加载器的类型,只需使用工厂
newInstance(URL,parentClassLoader)方法包装它,然后使用
Thread.currentThread().setContextClassLoader()
安装新的类加载器+1个有趣的想法,在一个main中创建类路径,然后调用另一个。