Как использовать киотокабинет (JNI) в игровой структуре? - PullRequest
1 голос
/ 16 ноября 2011

Я решаю использовать киотокабинет в Playframework.и произошла следующая ошибка.

Я использую Eclipse и playframework-1.2.3.а kyotocabinet - это нативная библиотека, поэтому я использую ее Java-Binding.

Воспроизвести код очень просто.в контроллере:

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 в Java Build Path> Source> Native Library Расположение моего проекта playframework.и это было хорошо в других проектах.

Как использовать нативную библиотеку в 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 не может загрузить собственную библиотеку.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 должен найти его автоматически.

кто-нибудь может использовать JNI в playframework?

наконец, я мог бы использовать kyotocabinet в качестве режима PROD, но не в режиме DEV.

Project / conf / application.conf

#application.mode=dev
application.mode=prod

Ответы [ 2 ]

1 голос
/ 16 ноября 2011

Полагаю, вам просто нужно загрузить dll в Java через System.load

Если вы разместите ddl в своем проекте, вы можете загрузить его через Play.getFile внутри вашего контроллера @OnApplicationStart. Это должно сделать его доступным для вашего приложения, пока JVM активна.

EDIT:

@ KenichiYamamoto Play.getFile получает файлы из пути приложения. Вы пытаетесь использовать полный путь там.

Прочтите о загрузке файла в контейнер. Возможно, из-за системы Play-compile-reload вы столкнулись с «уже загруженной» ошибкой. Попробуйте следовать примеру, добавив System.load в статический блок в вашем @ OnApplicationStart

0 голосов
/ 16 ноября 2011

Делайте, как говорит pere, но используйте относительный путь от корня вашего приложения. Не абсолютный путь. То есть Play.getFile ( "Lib \ myfile.dll")

...