2011-11-16 99 views
1

我正在處理在Playframework中使用kyotocabinet。 併發生以下錯誤。如何在playframework中使用kyotocabinet(JNI)?

我使用Eclipse和playframework-1.2.3。 和kyotocabinet是本地庫,所以我使用它的Java綁定。

重現代碼很簡單。 在控制器:

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位置。 ,在其他項目中效果很好。

如何在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會自動找到它。

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

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

項目/ conf目錄/ application.conf

#application.mode=dev 
application.mode=prod 

回答

1

我假設你只需要如果將DDL您的項目通過System.load

加載DLL爲Java,您可以通過Play.getFile加載在您的@OnApplicationStart控制器中。這應該會在JVM處於活動狀態時讓您的應用程序可用。

編輯:

@KenichiYamamoto Play.getFile從應用程序路徑獲取文件。你正試圖在那裏使用完整的路徑。

Read this關於將文件加載到容器中。這可能是(由於Play編譯 - 重載系統),你正在觸及「已經加載」的錯誤。嘗試通過添加系統來遵循示例。在你的@OnApplicationStart中加載一個靜態塊

+0

感謝您的建議。我添加了結果。 – KenichiYamamoto

+0

@KenichiYamamoto請參閱更新 –

0

按照pere的說法,但使用應用程序根目錄中的相對路徑。不是絕對路徑。即Play.getFile(「lib \ myfile.dll」)