我正在使用DJ而我正在显示原生文件对话框。要显示这些,它需要一个特定于操作系统的库。该库有一些dll文件以及一些类。我想加载特定的库(Windows,Linux或Mac),具体取决于它运行的操作系统。我试过System.load()
但是看起来这只加载了dll文件而不是带有它们的jar和其他类,因为我得到了这个错误。
System.load(System.getProperty("user.dir")+"/binaries/lib/swt-win64.jar");
Exception in thread "main" java.lang.UnsatisfiedLinkError: E:\Eclipse\workspace\PinewoodDerby\binaries\lib\swt-win64.jar: Can't load this .dll (machine code=0x4ba4) on a AMD 64-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(Unknown Source)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
at derby.DerbyProgram.<init>(DerbyProgram.java:144)
at derby.DerbyProgram.getInstance(DerbyProgram.java:119)
at derby.DerbyProgram.main(DerbyProgram.java:110)
我从Eclipse的网站下载了jar,刚刚提取swt.jar
并将其重命名为swt-win64.jar
如果我在类路径中包含swt-win64.jar
,那么一切正常,但这意味着此构建仅适用于64位Windows而不是其他任何东西,我希望同一个jar可以在所有平台上运行。
更新:当我使用this帖子的代码加载swt jar时,我得到了这个例外:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/SWT
at chrriis.dj.nativeswing.swtimpl.core.SWTNativeInterface.initialize_(SWTNativeInterface.java:213)
at chrriis.dj.nativeswing.swtimpl.NativeInterface.initialize(NativeInterface.java:71)
at chrriis.dj.nativeswing.swtimpl.core.SWTNativeInterface.open_(SWTNativeInterface.java:337)
at chrriis.dj.nativeswing.swtimpl.NativeInterface.open(NativeInterface.java:100)
at derby.DerbyProgram.<init>(DerbyProgram.java:161)
at derby.DerbyProgram.getInstance(DerbyProgram.java:130)
at derby.DerbyProgram.main(DerbyProgram.java:121)
Caused by: java.lang.ClassNotFoundException: org.eclipse.swt.SWT
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
我读了代码,addUrlMethod.invoke(classLoader, swtFileUrl)
我们在这里使用的方法,addURL
这似乎是我们正在添加一个URL而不是实际加载类。我使用-verbose
参数启动了我的程序,它没有说明加载SWT的任何内容。这是我目前加载类的代码:
private void loadSWTJar() throws MalformedURLException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
String osName = System.getProperty("os.name").toLowerCase();
String osArch = System.getProperty("os.arch").toLowerCase();
URLClassLoader classLoader = (URLClassLoader) getClass().getClassLoader();
Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addUrlMethod.setAccessible(true);
String swtFileNameOsPart = osName.contains("win") ? "win" : osName.contains("mac") ? "maco" : osName.contains("linux") || osName.contains("nix") ? "linux" : ""; // throw new RuntimeException("Unknown OS name: "+osName)
String swtFileNameArchPart = osArch.contains("64") ? "64" : "32";
String swtFileName = "swt-" + swtFileNameOsPart + "-" + swtFileNameArchPart + ".jar";
URL swtFileUrl = new URL("file:" + System.getProperty("user.dir") + "/lib/"+swtFileName);
System.out.println(addUrlMethod.invoke(classLoader, swtFileUrl));
System.out.println("Loaded SWT jar: " + swtFileUrl);
}
更新2:我得到了这个代码,但它只适用于Windows机器。我在Windows上没有收到任何错误,但我收到同样的错误:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/SWT
这是我的新代码:
private String getSwtJarName() throws OSNotDetectedException {
String swtFileName = "swt-" + getOS() + ".jar"; //$NON-NLS-1$ //$NON-NLS-2$
return swtFileName;
}
private String getOS() throws OSNotDetectedException {
String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
String os = osName.contains("win") ? "win" : osName.contains("mac") ? "mac" : osName.contains("linux") || osName.contains("nix") ? "linux" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
if ("".equals(os)) { //$NON-NLS-1$
throw new OSNotDetectedException();
}
return os + "-" + getArch(); //$NON-NLS-1$
}
class OSNotDetectedException extends Exception{
private static final long serialVersionUID = 1L;
OSNotDetectedException(){}
OSNotDetectedException(Throwable e){
super(e);
}
}
private String getArch() {
String jvmArch = System.getProperty("os.arch").toLowerCase(); //$NON-NLS-1$
String arch = jvmArch.contains("64") ? "64" : "32"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return arch;
}
private void loadSWT() throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, OSNotDetectedException {
String prefix;
if (debugMode) {
prefix = "binaries/lib"; //$NON-NLS-1$
} else {
prefix = "lib"; //$NON-NLS-1$
}
String swtJarName = prefix + "/" + getSwtJarName(); //$NON-NLS-1$
System.out.println("Loading SWT:"); //$NON-NLS-1$
System.out.println(swtJarName);
addFile(swtJarName);
try {
NativeInterface.open();
}
catch (NoClassDefFoundError e) {
throw new OSNotDetectedException(e);
}
}
private static void addFile(String s) throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
File f = new File(s);
addFile(f);
}
private static void addFile(File f) throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
addURL(f.toURI().toURL());
}
private static void addURL(URL u) throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> sysclass = URLClassLoader.class;
@SuppressWarnings("rawtypes")
Class[] parameters = new Class[] { URL.class };
Method method = sysclass.getDeclaredMethod("addURL", parameters); //$NON-NLS-1$
method.setAccessible(true);
method.invoke(sysloader, new Object[] { u });
}