2014-10-09 61 views
1

我試圖運行使用mallet library的LDA算法。當我嘗試用一​​組參數運行LDA是確定的,但與另一組我有這樣的錯誤:如何從Java中的外部jar中捕獲異常

09-Oct-2014 23:50:24.354 INFO [http-nio-8084-exec-127] cc.mallet.topics.ParallelTopicModel.estimate <50> LL/token: -8.73265 
09-Oct-2014 23:50:24.657 INFO [http-nio-8084-exec-127] null.null [beta: 0.00795] 
09-Oct-2014 23:50:24.657 INFO [http-nio-8084-exec-127] null.null <60> LL/token: -8.6299 
09-Oct-2014 23:50:24.957 INFO [http-nio-8084-exec-127] cc.mallet.topics.ParallelTopicModel.estimate <70> LL/token: -8.61982 
09-Oct-2014 23:50:25.019 INFO [http-nio-8084-exec-127] null.null [beta: 0.00583] 
09-Oct-2014 23:50:25.263 INFO [http-nio-8084-exec-127] cc.mallet.topics.ParallelTopicModel.estimate <80> LL/token: -8.89656 
09-Oct-2014 23:50:25.402 INFO [http-nio-8084-exec-127] null.null [beta: 0.00484] 

java.lang.ArrayIndexOutOfBoundsException: -1 at 
cc.mallet.topics.WorkerRunnable.sampleTopicsForOneDoc(WorkerRunnable.java:489) at 
cc.mallet.topics.WorkerRunnable.run(WorkerRunnable.java:275) at 
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)  at 
java.util.concurrent.FutureTask.run(FutureTask.java:266) at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)  at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)  at 
java.lang.Thread.run(Thread.java:745) java.lang.ArrayIndexOutOfBoundsException: -1 at 
cc.mallet.topics.WorkerRunnable.sampleTopicsForOneDoc(WorkerRunnable.java:489) at 
cc.mallet.topics.WorkerRunnable.run(WorkerRunnable.java:275) at 
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)  at 
java.util.concurrent.FutureTask.run(FutureTask.java:266) at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)  at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)  at 
java.lang.Thread.run(Thread.java:745) 

我的代碼如下所示:

try{ 
    //call some function from library 
} catch(Exception e){ 
    System.out.println("LDA Exception") 
} 

如何能趕上因外部罐例外?我有蘆葦this問題,但它不適合我。任何想法?

編輯:

我的項目是其Apache Tomcat服務器上運行RESTful Web服務。我嘗試在dopost函數中調用lda算法。

編輯2

槌是一個開源庫。所以我試着閱讀代碼,並找到下面的代碼。

public class ParallelTopicModel implements Serializable { 
    int numThreads = 2; 
    public void estimate() throws IOException { 
     WorkerRunnable[] runnables = new WorkerRunnable[numThreads]; 
     for (int thread = 0; thread < numThreads; thread++) { 
      runnables[thread] = new WorkerRunnable(numTopics, alpha, alphaSum, beta, 
                random, data, runnableCounts, 
                runnableTotals, offset, docsPerThread); 
     //some code 
     } 
    } 

} 

public class WorkerRunnable implements Runnable { 

    public void run() { 

     try { 
      //some code 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 

我的web服務:

@POST 
@Produces("application/xml") 
public String getXml(@FormParam("xmlinput") String xmlinput) throws Exception { 
try { 
    //call estimate function in ParallelTopicModel class 
    //return an xml; 
} catch (Exception e) { 
    return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<modelingOutput>null</modelingOutput>"; 
} 

那麼,怎樣才能處理我的web服務whiche產生WorkRunnable類異常。我想ruturn一個xml樣子

`null

我已經閱讀了很多像thisthis問題,但我不找到解決方案

+0

你寫的代碼有什麼問題?這是不是趕上了表演? – EJK 2014-10-09 21:07:20

+0

我的代碼捕獲所有異常。這個例外不是來自我的代碼。它來自jar文件 – Jimmysnn 2014-10-09 21:08:38

+0

這不就是一個記錄語句嗎?您的代碼是否會停止運行,因爲異常冒泡或者您只是因爲外部jar打印了某些東西而煩惱? – 2014-10-09 21:11:03

回答

3

這裏的問題不在於呼叫外部罐子。在調用鏈中的任何方法拋出的異常(無論實際類的字節碼存儲在何處)都會在第一個鏈中捕獲到catch

您在這裏遇到的問題是異常發生在另一個線程中。如果從代碼中啓動單獨的線程,則該線程中的異常不會傳遞到您的線程。就您的代碼而言,該呼叫已完成。如果其他線程中的代碼沒有捕獲到它們,那麼它們將被該線程的異常處理程序捕獲,如果有這樣的處理程序。

運行時錯誤通常是由錯誤輸入引起的,所以避免它們的通常策略是理解爲什麼您的參數會導致該方法中的數組索引爲負數,然後確保您從不將該參數傳遞給該方法。

如果這是不可能的,你可以爲線程創建一個異常處理程序。只有當你是創建線程的控制者,並且你可以在其中設置處理程序時,這纔會起作用。

有關處理線程異常的更多信息,請參閱this question

編輯

自從WorkerRunnable代碼似乎捕獲所有異常(並打印堆棧跟蹤),沒有辦法自己趕上他們。你可以做以下兩件事之一:

  1. 正如我上面所說的,檢查你通過什麼參數導致數組超出界限錯誤,並避免這些條件。使用if語句,如果參數不正確,請輸出<modelingOutput>null</modelingOutput>輸出 - 無需首先運行建模。
  2. 使用它們的源代碼,將它們的catch子句更改爲設置變量的內容,該變量告訴您​​存在異常,將其編譯並使用該jar而不是他們的jar。這就是開源的目的。您可能希望與該庫的維護人員進行交流,並告訴他們如果他們添加了一種方法來檢測是否有一個異常是由其中一個子線程引起的,那將會很不錯。
+0

Thnaks爲您的答案。請參閱編輯2.我的問題現在有點不同了。 – Jimmysnn 2014-10-11 10:57:22

+0

@Jimmysnn我已經編輯了我的答案。 – RealSkeptic 2014-10-11 13:22:05

+0

Thnak你的編輯,但是, 1)我無法驗證參數,因爲我不知道什麼時候它是不好的 2)這是很難改變他們的代碼。我想與該庫的維護人員溝通,但現在我必須找到解決方案。 所以我可以檢查其他進程的線程是否存在或崩潰? 我讀過這篇文章http://stackoverflow.com/questions/702415/how-to-know-if-other-threads-have-finished,我不知道是否可以處理異常這樣的事情 – Jimmysnn 2014-10-11 13:28:21