Как использовать киотокабинет (JNI) в игровой структуре?
Я решаю использовать киотокабинет в 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 Location моего проекта 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.
Проект / CONF /application.conf
#application.mode=dev
application.mode=prod
2 ответа
Я предполагаю, что вам просто нужно загрузить DLL в Java через System.load
Если вы поместите ddl в свой проект, вы можете загрузить его через Play.getFile в вашем контроллере @OnApplicationStart. Это должно сделать его доступным для вашего приложения, пока JVM активна.
РЕДАКТИРОВАТЬ:
@KenichiYamamoto Play.getFile получает файлы из пути приложения. Вы пытаетесь использовать полный путь там.
Прочтите это о загрузке файла в контейнер. Возможно, из-за системы Play-compile-reload вы столкнулись с "уже загруженной" ошибкой. Попробуйте следовать примеру, добавив System.load в статический блок в вашем @OnApplicationStart.
Делайте, как говорит Пер, но используйте относительный путь от корня вашего приложения. Не абсолютный путь. Т.е. Play.getFile("lib\myfile.dll")