【问题标题】:How to catch exception from external jar in Java如何在 Java 中从外部 jar 中捕获异常
【发布时间】:2014-12-04 22:37:37
【问题描述】:

我正在尝试使用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")
}

如何捕获由外部 jar 引起的异常?我有this 的问题,但它对我不起作用。有什么想法吗?

编辑:

我的项目是一个在 apache tomcat 服务器上运行的 RESTful Web 服务。我尝试在 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 变成

`空

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

【问题讨论】:

  • 你写的代码有什么问题?那不赶上执行吗?
  • 我的代码捕获所有异常。这个异常不是来自我的代码。它来自 jar 文件
  • 这不只是一个日志语句吗?您的代码是否因为异常冒泡而停止运行,或者您只是因为外部 jar 打印了一些东西而感到困扰?
  • 因为外部jar打印错误。
  • 如果它打印到 System.out,您无能为力。异常永远不会进入您的代码。如果 jar 记录信息,为什么会出现问题?您可以随时将您的System.out 重定向到不同的PrintStream,但我建议您不要这样做。这也意味着您将无法再自己使用控制台。 编辑:Mallet 似乎使用java.util.logging,因此您可以通过调整根记录器来禁用控制台输出:stackoverflow.com/questions/2533227/…

标签: java exception-handling mallet


【解决方案1】:

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

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

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

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

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

编辑

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

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

【讨论】:

  • 感谢您的回答。请参阅编辑 2。我的问题现在有点不同了。
  • 感谢您的编辑,但是,1) 我无法验证参数,因为我不知道什么时候出现问题 2) 更改他们的代码非常困难。我想与该库的维护者沟通,但现在我必须找到解决方案。那么我可以检查其他进程的线程是否处于活动状态或崩溃?我读了这篇stackoverflow.com/questions/702415/… 的帖子,我想知道是否可以处理类似这样的异常
  • 对不起@Jimmysnn,这对你没有帮助。首先,您无法访问这些线程,因为它们的引用是您无法控制的方法中的局部变量。但即使你可以,也没有办法区分失败的运行和成功的运行。因为他们有一个try...catch 块,所以线程总是成功终止。它从不抛出异常。
猜你喜欢
  • 1970-01-01
  • 2021-06-13
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
相关资源
最近更新 更多