1

I wanted to add a .so file for running my project in Linux. And for running it on Windows i should use a .dll file. when I change my OS each time, I used set the path by selecting the Java Build Path>>libraries>> and editing the native library location as in this answer

I tried by adding these file into the class path but it didn't worked.

How can i choose the file based on the Operating System?

Community
  • 1
  • 1
jos
  • 1,082
  • 5
  • 19
  • 45

2 Answers2

1

No, because native libraries have different file format in Linux and Windows. If you had a java library it should be just .jar, but in case of native you need both implementations.

And no, you can't choose one of them automatically in eclipse configuration (at least to my knowledge)

user2660000
  • 332
  • 2
  • 3
  • i tried with system.load("pathtofile/file.so") its was working. i was looking for any other option. thanks @user2660000 – jos Nov 19 '13 at 13:38
  • you can use `System.getProperty("os.name")` and a logical operator to load one or the other lib – user2660000 Nov 19 '13 at 14:10
1

When you launch your project in Eclipse, you can use a custom classloader to alter the automatic java.library.path and parse os.name and os.arch to detect the current os and java architecture. I use it in my project:

1) Name your native library folders like this:

linux-amd64
linux-x86
win32-amd64
win32-x86

Why win32? Because it matches eclipse ${system:OS} variable. Unfortunately, ${system:ARCH} or ${system_property:os.arch} don't depend on the runtime JRE, otherwise we wouldn't need a custom classloader.

2) Create in the same place an extra folder named nativelibArch

3) Refresh your project in eclipse

4) Point native library location to nativelibArch

5) Create class PlatformParser (see below). It will return a right folder name from system properties (Or you can pass ${system:OS} as another JVM parameter)

6) Create class EclipseNativeFixer (see below). It will alter at project startup java.library.path generated by eclipse

7) In your launch configurations ad VM option -Djava.system.class.loader=test.EclipseNativeFixer

package test;

import java.util.Properties;

public class PlatformParser {

    public static String nativelibArch() {
        return genericOs() + "-" + System.getProperty("os.arch");
    }

    public static String genericOs() {
        return genericOs(System.getProperties());
    }

    public static String genericOs(Properties sysprops)
    {
        String osname = sysprops.getProperty("os.name");
        if (osname == null)
            return null;
        osname = osname.toLowerCase();
        if (osname.startsWith("linux"))
            return "linux";
        if (osname.startsWith("windows"))
            return "win32";
        if (osname.startsWith("freebsd"))
            return "freebsd";
        if (osname.startsWith("solaris"))
            return "solaris";
        if (osname.equals("aix"))
            return "aix";
        if (osname.startsWith("digital unix"))
            return "digital-unix";
        if (osname.equals("hp ux"))
            return "hpux";
        if (osname.equals("irix"))
            return "irix";
        if (osname.startsWith("mac os"))
            return "macos";
        if (osname.equals("mpe/ix"))
            return "mpe-ix";
        if (osname.equals("os/2"))
            return "os-2";
        if (osname.startsWith("netware"))
            return "netware";
        return null;
    }
}

_

package test;

import java.lang.reflect.Field;

public class EclipseNativeFixer extends ClassLoader {

    public static void setLibraryPath(String path) throws Exception {
        System.setProperty("java.library.path", path);

        //set sys_paths to null
        final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
        sysPathsField.setAccessible(true);
        sysPathsField.set(null, null);
    }

    public EclipseNativeFixer(ClassLoader parent) {
        super(parent);

        String nativelibArch = PlatformParser.nativelibArch();
        String lipbat = System.getProperty("java.library.path");
        if (lipbat != null) {
            lipbat = lipbat.replaceAll("nativelibArch", nativelibArch);
            try {
            setLibraryPath(lipbat);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
basin
  • 3,949
  • 2
  • 27
  • 63