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

Jim*_*snn 2 java exception mallet

我尝试使用mallet 库运行 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)
Run Code Online (Sandbox Code Playgroud)

我的代码如下所示:

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

如何捕获外部jar引起的异常?我已经回答过这个问题,但它对我不起作用。任何想法?

编辑:

我的项目是一个安静的网络服务,它运行在 apache tomcat 服务器上。我尝试在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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我的网络服务:

@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>";
}
Run Code Online (Sandbox Code Playgroud)

那么如何处理在我的 Web 服务中产生 WorkRunnable 类的异常。我想要 ruturn 一个 xml 看起来像

`空

我读过很多这样的问题,没有找到解决方案

Rea*_*tic 5

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

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

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

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

您可能想查看此问题以了解有关处理线程中异常的更多信息。

编辑

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

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


归档时间:

查看次数:

5166 次

最近记录:

11 年,4 月 前