如何从Java中捕获外部jar的异常

时间:2014-10-09 21:04:25

标签: java exception-handling mallet

我尝试使用mallet library运行LDA算法。当我尝试使用一组参数运行LDA时,它可以,但是使用另一组我有这个错误:

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个问题,但这对我不起作用。有什么想法吗?

修改

我的项目是一个安静的Web服务,它运行在apache tomcat Server上。我尝试在dopost函数中调用lda算法。

编辑2

Mallet是一个开源库。所以我试着阅读代码,然后找到了下面的代码。

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();
        }
    }

}

我的网络服务:

@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服务中生成WorkRunnable类的异常。我想要将xml看起来像

  

`null

我已经阅读了很多问题,例如thisthis,但我找不到解决方案

1 个答案:

答案 0 :(得分:3)

这里的问题不在于调用外部jar。您的调用链中的任何方法抛出的异常,无论实际类的字节码存储在何处,都会在链的第一个catch块处被捕获。

您遇到的问题是异常发生在另一个线程中。如果从代码中启动一个单独的线程,则该线程中的异常不会传递给您的线程。就您的代码而言,该调用已完成。如果另一个线程中的代码没有捕获它们,那么如果存在这样的处理程序,它们将被该线程的异常处理程序捕获。

运行时错误通常是由输入错误引起的,因此通常的避免错误的策略是理解为什么你的参数导致该方法中的数组索引为负数,然后确保你永远不会将这些参数传递给该方法。

如果这是不可能的,您可以为该线程创建一个异常处理程序。只有当你是控制创建线程的人并且可以在其中设置处理程序时,这才有效。

您可能需要查看this question,了解有关处理线程中异常的更多信息。

修改

由于他们的WorkerRunnable代码似乎捕获了所有异常(并打印了堆栈跟踪),因此无法自己捕获它们。你可以做以下两件事之一:

  1. 正如我上面所说,检查您传递的参数导致数组越界错误,并避免这些条件。使用if语句,如果参数不正确,请打印<modelingOutput>null</modelingOutput>输出 - 而不是首先运行建模。
  2. 使用他们的源代码,将他们的catch子句更改为设置变量的东西,该变量告诉您​​有异常,编译它并使用该jar而不是他们的。这就是开源的用途。您可能希望与该库的维护者进行通信,并告诉他们如果他们添加了一种方法来检测异常是否由其中一个子线程引起,那将会很好。