【问题标题】:How do I load and use native library in java?如何在 Java 中加载和使用本机库?
【发布时间】:2012-07-31 18:55:31
【问题描述】:

我有一个 java 类,调用本地方法并尝试加载库:

import java.io.UnsupportedEncodingException;

public class Main {

    public static native String getMyString(String s);

    /**
     * @param args
     * @throws UnsupportedEncodingException
     */
    public static void main(String[] args) throws UnsupportedEncodingException {
        // TODO Auto-generated method stub
        // System.out.println("here!");

        String s2 = getMyString("string text");
        for (Byte b : s2.getBytes("UTF-8")) {
            System.out.print(b);
            System.out.print(",");
        }

    }

    static {
        System.loadLibrary("mylib.so");
    }

}

“mylib.so”在 Main.class 所在的目录中。

当我运行java Main 时,出现以下异常:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no mylib.so in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1856)
        at java.lang.Runtime.loadLibrary0(Runtime.java:845)
        at java.lang.System.loadLibrary(System.java:1084)
        at Main.<clinit>(Main.java:24)

我应该改变什么才能让这个wark?

我尝试设置库完整路径但没有成功

【问题讨论】:

标签: java native


【解决方案1】:

“如何加载原生库”

public final class NativeLibsLoaderUtil {
    private static final String JAVA_LIBRARY_PATH = "java.library.path";
    private static final String SYS_PATHS = "sys_paths";

    private NativeLibsLoaderUtil() {
    }

    private static void addLibsToJavaLibraryPath(final String tmpDirName) {
        try {
            System.setProperty(JAVA_LIBRARY_PATH, tmpDirName);
            /* Optionally add these two lines */
            System.setProperty("jna.library.path", tmpDirName);
            System.setProperty("jni.library.path", tmpDirName);
            final Field fieldSysPath = ClassLoader.class.getDeclaredField(SYS_PATHS);
            fieldSysPath.setAccessible(true);
            fieldSysPath.set(null, null);
        } catch (IllegalAccessException | NoSuchFieldException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }   
}

其中 tmpDirName 是您存储库的目录。 或者您可以修改上述类并使用系统属性中的临时目录,如下所示:

/**
 * Temporary directory system property name
 */
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";

/**
 *
 * @return
 */
private static File getTempDir() {
    final String tmpDirName = System.getProperty(JAVA_IO_TMPDIR);
    final File tmpDir = new File(tmpDirName);
    if (!tmpDir.exists()) {
        tmpDir.mkdir();
    }
    return tmpDir;
}

!但首先你必须将你的本地库复制到那里:)

然后在执行任何类构造函数之前,在“最根”类的静态块中加载本机库调用“addLibsToJavaLibraryPath”方法。

static {
    NativeLibsLoaderUtil.addLibsToJavaLibraryPath("/tmp");
}

【讨论】:

    【解决方案2】:

    正如雷默斯回答的那样。 或者你可以使用 System.load("/Library/Path/libsample.so");

    【讨论】:

      【解决方案3】:

      执行以下操作:

      • 使用 System.loadLibrary("mylib");
      • 将 mylib.so 复制到 libmylib.so
      • 运行 java -Djava.library.path=/root/ Main

      【讨论】:

      • 启动java时也使用-Djava.library.path=path-to-lib-file。
      • 我进行了更改并使用 java Main -Djava.library.path=/root/ 运行程序,但没有任何成功
      • 请注意,传递给-Djava.library.path的路径必须是绝对路径。
      【解决方案4】:

      您应该将 so 添加到库路径: -Djava.libarary.path=(这是在 java 命令中)。

      如果你从 Eclipse 运行: How to add native library to "java.library.path" with Eclipse launch (instead of overriding it)

      【讨论】:

        猜你喜欢
        • 2014-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-24
        • 2012-08-01
        • 1970-01-01
        相关资源
        最近更新 更多