java - 如何在playframework中使用kyotocabinet(JNI)?

标签 java java-native-interface playframework kyotocabinet

我正在尝试在 Playframework 中使用 kyotocabinet。 并发生以下错误。

我正在使用 Eclipse 和 playframework-1.2.3。 kyotocabinet 是 native 库,因此我使用它的 Java 绑定(bind)。

重现代码很简单。 在 Controller 中:

public static void somePage() {
    DB db = new DB();//error occurred
    render();
}

Internal Server Error (500) for request GET /
Execution exception (In /app/controllers/TestApp.java around line 45)
NoClassDefFoundError occured : Could not initialize class kyotocabinet.DB

play.exceptions.JavaExecutionException: Could not initialize class kyotocabinet.DB
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:229)
    at Invocation.HTTP Request(Play!)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class kyotocabinet.DB
    at controllers.TestApp.somePage(TestApp.java:45)
    at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:546)

    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:500)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:476)

    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:471)

    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:159)
    ... 1 more

Eclipse 中的构建已完成,但运行时出现错误。

我猜是因为kyotocabinet.dll丢失了。(只找到了jkyotocabinet.jar) 我将 kyotocabinet.dll 的位置配置为我的 playframework 项目的 Java Build Path > Source > Native Library Location。 在其他项目中也表现良好。

如何在playframework中使用原生库? 有示例或教程吗?

Play.getFile 和 System.load 不起作用。

package controllers;
import play.Play;
import play.jobs.*;

@OnApplicationStart
public class Bootstrap extends Job {
public void doJob() {
    String path = "D:/MyProject/lib/jkyotocabinet.dll";
    Play.getFile(path);
    //System.load(path); if this was enabled, following error occurred: "Native Library D:\MyProject\lib\jkyotocabinet.dll already loaded in another classloader". so I guess the dll was loaded.
    System.out.println("bootstrap loaded");//this is displayed.
}
}

UnsatisfiedLinkError occured : no jkyotocabinet in java.library.path

这个日本博客告诉 Play!Framework 无法加载 native 库。 http://d.hatena.ne.jp/hjym_u/20110702/1309609277

我已经尝试过这些:绝对路径、相对路径、System.load、System.loadLibrary、Play.getFile。

作为最终的方法,我将 jkyotocabinet.dll 放入当前目录(D:/MyProejct/),并编写了这段代码。

public static void somePage(){
    File f = Play.getFile("jkyotocabinet.dll");
        if(f != null && f.isFile() && f.canRead() && f.canExecute()){//true
            DB db = new DB();//error occured. it reached here.
        }
    render();
}

Execution exception
NoClassDefFoundError occured : Could not initialize class kyotocabinet.DB

Play.getFile 找到了路径“jkyotocabinet.dll”,因此 jkyotocabinet.dll 位于当前目录中,因此 jvm 应该会自动找到它。

任何人都可以在 playframework 中使用 JNI 吗?

最后,我可以使用 kyotocabinet 作为 PROD 模式,但不能使用 DEV 模式。

项目/conf/application.conf

#application.mode=dev
application.mode=prod

最佳答案

我假设你只需要通过System.load将dll加载到Java中

如果您将 ddl 放在您的项目中,您可以通过 Play.getFile 加载它在您的 @OnApplicationStart Controller 内。这应该可以使其在 JVM 处于 Activity 状态时可供您的应用程序使用。

编辑:

@KenichiYamamoto Play.getFile 从应用程序路径获取文件。您正在尝试在那里使用完整路径。

Read this关于将文件加载到容器中。可能是(由于 Play 编译重新加载系统)您遇到了“已加载”错误。尝试按照示例将 System.load 添加到 @OnApplicationStart 的静态 block 内

关于java - 如何在playframework中使用kyotocabinet(JNI)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8148758/

相关文章:

java - 字节数组的 JNI 内存泄漏

java - 使用 Play Framework 在应用程序中检索端口号

Java - 日期格式

java - 快速替换 XML 节点值

java - java中使用java.awt.Graphics2D的变形图像

java - JNI GetByteArrayElements () 错误

java - 基于 Spring 注释的 DI 与 xml 配置?

java - Java 和 Haskell 之间的通信

java - 如何在 Play Framework 中使用 WebSockets?

scala - Play 2.0 Framework (scala) 中的异步结果