2014-10-09 63 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