0

I am using DJ and I am displaying the native file dialogs. To display these, it needs a library specific to the OS. The library has some dll files as well as some classes. I would like to load the specific library (Windows, Linux, or Mac) depending on the OS it is running. I tried System.load() but it appears that this loads just the dll files and not a jar with them and other classes as I get this error. 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)

I downloaded the jar from Eclipse's website and just extracted swt.jar and renamed it to swt-win64.jar

Everything works fine if I include swt-win64.jar in my class path but this means that this build only works for 64-bit Windows and nothing else, I would like the same jar to work on all platforms.

UPDATE: When I load the swt jar with the code from this post, I get this exception:

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

I read over the code, addUrlMethod.invoke(classLoader, swtFileUrl) the method we are using here, addURL this seems that we are adding a URL and not actually loading the classes. I launched my program with the -verbose argument and it didn't say anything about loading the SWT. This is my current code for loading the classes:

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);
    }

UPDATE 2: I got this code working but it only works on a Windows machine. I do not receive any error on Windows but I get the same error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/SWT

Here is my new code:

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 });
    }
Community
  • 1
  • 1

0 Answers0