禁止Java异常堆栈跟踪

时间:2018-10-09 21:56:37

标签: java

我用Java编写了一个脚本,用于从第三方SOAP API下载数据。我必须对此API进行多次请求才能获取所需的所有数据。第三方SOAP API时不时会给我错误。它给我的错误是java.lang.NumberFormatException: Invalid date/time,当我使用从WSDL生成的代码读取SOAP答复时发生。发生这种情况时,我会将特定请求添加到请求列表中,然后重试。在尝试了第一批请求之后,我会不断重试失败的请求,直到所有请求成功为止。

我捕获了异常,但是无论何时发生异常,它们仍会向控制台输出堆栈跟踪。这是一个问题,因为我正在通过电子邮件将Java程序的输出发送给非技术人员,并且堆栈跟踪只是在电子邮件中填充了与收件人无关的信息。无论如何,有没有抑制这些堆栈痕迹?我知道我可以只从Java发送电子邮件,而不是通过电子邮件发送Java程序的输出,但是我认为应该有一些抑制堆栈跟踪的方法,考虑到我已经有了Java程序的输出,这将更加简单使用mailx作为电子邮件发送。

谢谢。

编辑:

我没有打印堆栈跟踪。这是我的代码的通用版本:

class Updater {
    static Stream<Datum> update(Collection<Datum> data) {
        data.parallelStream().map(datum -> Client.update(datum));
    }
}

class Client {
    static Datum update(Datum datum) {
        Request = new Request();
        return processRequest(request, datum);
    }

    static Datum processRequest(Request request, Datum datum) {
        Reply reply = null;
        try {
            reply = new ServiceLocator().getServicePort(new URL(endpointAddress)).getUpdates(request);
            update(datum, reply);
        catch (Exception e) {
            logger.warning("There was en error reading the response for " + datum);
        }
        return route;
    }
}

我的记录器记录到文件,而不是控制台。我的文件有2500行,如下所示:

There was an error reading the response for detail x and distinction y.

与此同时,我的电子邮件中的输出大约有20个错误,如下所示:

org.xml.sax.SAXException: Invalid date/time
java.lang.NumberFormatException: Invalid date/time
    at org.apache.axis.encoding.ser.SimpleDeserializer.onEndElement(SimpleDeserializer.java:180)
    at org.apache.axis.encoding.DeserializerImpl.endElement(DeserializerImpl.java:502)
    at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
    at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:171)
    at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
    at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
    at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
    at org.apache.axis.client.Call.invoke(Call.java:2467)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
    at com.vendor.stub.ServiceSoapBindingStup.getUpdates(ServiceBindingStup.java.2364)
    at com.mycompany.Client.processRequest(Client.java.16)
    at com.mycompany.Client.update(Client.java.10)
    at com.mycompany.Updater.lambda$update$0(Updater.java.2)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
    at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
    at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
    at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.NumberFormatException: Invalid date/time
    at org.apache.axis.encoding.ser.CalendarDeserializer.makeValue(CalendarDeserializer.java:75)
    at org.apache.axis.encoding.ser.SimpleDeserializer.onEndElement(SimpleDeserializer.java:172)
    ... 26 more

编辑:

这不是理想的选择,但是我通过将Java程序的输出写入标准错误来解决此问题,然后我通过电子邮件将标准错误而不是标准输出发送给了我。堆栈跟踪仅被写入标准输出。

1 个答案:

答案 0 :(得分:0)

您可以尝试三种选择:

选项1)捕获异常时,请勿打印该异常。

try {
    //some code
} catch(SomeException e) {
    //You might be printing the exception here like e.printStackTrace(). Remove those lines of code
}

选项2)将异常写入另一个文件,并将普通输出写入另一个文件,如下所示:

try {
    //your code
} catch(SomeException e) {
    System.setOut(new PrintStream(new FileOutputStream("exceptions.txt")));
    // print exception
    e.printStackTrace();
} finally {
    System.setOut(new PrintStream(new FileOutputStream("normaloutput.txt")));
}

选项3)以以下方式使用printStackTrace方法(如果您的Java代码是多线程的):

PrintStream errorStream = new PrintStream(new FileOutputStream("exceptions.txt"));
try {
    //your code
} catch(SomeException e) {
    // print exception to your stream
    e.printStackTrace(errorStream);
}
// no need of finally block