包括不同操作系统中java项目的编译库文件

时间:2013-11-19 13:19:09

标签: java eclipse native

我想添加一个 .so 文件,以便在Linux中运行我的项目。要在Windows上运行它,我应该使用 .dll 文件。当我每次更改操作系统时,我使用了设置路径  选择Java Build Path>> libraries>>并编辑本机库位置 as in this answer

我尝试将这些文件添加到类路径中,但它没有用。

如何根据操作系统选择文件?

2 个答案:

答案 0 :(得分:1)

不,因为本机库在Linux和Windows中具有不同的文件格式。如果你有一个java库,它应该只是.jar,但是在本机的情况下,你需要两个实现。

不,你不能在eclipse配置中自动选择其中一个(至少据我所知)

答案 1 :(得分:1)

在Eclipse中启动项目时,可以使用自定义类加载器来更改自动java.library.path并解析os.nameos.arch以检测当前的os和java体系结构。我在我的项目中使用它:

1)将您的本机库文件夹命名为:

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

为什么win32?因为它匹配eclipse ${system:OS}变量。不幸的是,${system:ARCH}${system_property:os.arch}不依赖于运行时JRE,否则我们不需要自定义类加载器。

2)在同一个地方创建一个名为nativelibArch

的额外文件夹

3)在eclipse中刷新你的项目

4)将本机库位置指向nativelibArch

5)创建课程PlatformParser(见下文)。它将从系统属性返回正确的文件夹名称 (或者您可以将$ {system:OS}作为另一个JVM参数传递)

6)创建课程EclipseNativeFixer(见下文)。它将在eclipse生成的项目启动java.library.path处改变

7)在您的启动配置广告虚拟机选项-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);
            }
        }
    }
}