java – setUncaughtExceptionHandler在Maven项目中不起作用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – setUncaughtExceptionHandler在Maven项目中不起作用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含9387字,纯文字阅读大概需要14分钟。
内容图文
![java – setUncaughtExceptionHandler在Maven项目中不起作用](/upload/InfoBanner/zyjiaocheng/780/d85ea70672c2468692319f7f8382eb70.jpg)
我正在尝试在我的应用程序中的主线程上处理未捕获的异常,因此我可以将它们记录到一个文件中(我的应用程序是一个命令行应用程序,它运行在一夜之间的工作,所以如果出现问题我希望管理员能够容易看到异常).我把它简化为尽可能简单的测试用例.
使用(根据getting started docs)生成的Maven应用程序:
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=com.mycompany.app \
-DartifactId=my-app
App.java:
package com.mycompany.app;
public class App {
public static void main(String[] args) throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Handled exception - let's log it!");
// Logging code here
}
});
System.out.println("Exception testing");
throw new Exception("Catch and log me!");
}
}
使用mvn exec:java生成:
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.mycompany.app:my-app:jar:1.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.codehaus.mojo:exec-maven-plugin is missing. @ line 20, column 15
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-app 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.4.0:java (default-cli) @ my-app ---
Exception testing
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.Exception: Catch and log me!
at com.mycompany.app.App.main(App.java:14)
... 6 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.493 s
[INFO] Finished at: 2015-10-26T10:57:00+00:00
[INFO] Final Memory: 8M/240M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.4.0:java (default-cli) on project my-app: An exception occured while executing the Java class. null: InvocationTargetException: Catch and log me! -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.4.0:java (default-cli) on project my-app: An exception occured while executing the Java class. null
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: An exception occured while executing the Java class. null
at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:345)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
... 20 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.Exception: Catch and log me!
at com.mycompany.app.App.main(App.java:14)
... 6 more
与简单的Java应用程序相同的代码运行正常. App.java:
public class App {
public static void main(String[] args) throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Handled exception - let's log it!");
// Logging code here
}
});
System.out.println("Exception testing");
throw new Exception("Catch and log me!");
}
}
运行javac App.java&& java App产生:
Exception testing
Handled exception - let's log it!
我怀疑给出的建议是“你不应该有任何未被捕获的例外”,但我不确定我是否保证这一点并且在任何情况下对Maven和非Maven结果之间的差异感到好奇.
解决方法:
JavaExecMojo不会分叉新进程.相反,它在与mojo相同的线程中调用main方法.因此,他们必须捕获main方法抛出的任何异常并模拟jvm的行为.
我认为这是maven exec插件中的一个错误.看一下ExecJavaMojo的源代码.
JavaExecMojo仅使用
Thread.currentThread().getThreadGroup().uncaughtException( Thread.currentThread(), e );
模拟未捕获的异常行为.但这是不正确的,因为如果没有为当前线程注册未捕获的异常处理程序,则仅由JVM调用ThreadGroup的uncaughtException方法.参见ThreadGroup.uncaughtException(Thread t, Throwable e)的javadoc.
Called by the Java Virtual Machine when a thread in this thread group stops because of an uncaught exception, and the thread does not have a specific Thread.UncaughtExceptionHandler installed.
我想开发人员想要做的是
try {
....
// invoke main method
} catch (Exception e) {
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler ueh = currentThread.getUncaughtExceptionHandler();
if (ueh == null) {
currentThread.getThreadGroup().uncaughtException(currentThread, e);
} else {
ueh.uncaughtException(currentThread, e);
}
}
这将模拟JVM的行为.
您可以使用defaultUncaughtExceptionHandler作为快速修复.
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Handled exception - let's log it!");
// Logging code here
}
});
编辑
However, using defaultUncaughtExceptionHandler produces the same java.lang.reflect.InvocationTargetException.
你是对的.他们做了另一招.他们使用自己的ThreadGroup实现.见IsolatedThreadGroup
class IsolatedThreadGroup extends ThreadGroup {
private Throwable uncaughtException; // synchronize access to this
public IsolatedThreadGroup( String name ){
super( name );
}
public void uncaughtException( Thread thread, Throwable throwable ) {
if ( throwable instanceof ThreadDeath ) {
return; // harmless
}
synchronized ( this ) {
if ( uncaughtException == null ) {
uncaughtException = throwable; // will be reported eventually
}
}
getLog().warn( throwable );
}
}
uncaughtException的javadoc强制执行
The uncaughtException method of ThreadGroup does the following:
- If this thread group has a parent thread group, the uncaughtException method of that parent is called with the same two arguments.
- Otherwise, this method checks to see if there is a default uncaught exception handler installed, and if so, its uncaughtException method is called with the same two arguments.
- Otherwise, this method determines if the Throwable argument is an instance of ThreadDeath. If so, nothing special is done. Otherwise, a message containing the thread’s name, as returned from the thread’s getName method, and a stack backtrace, using the Throwable’s printStackTrace method, is printed to the standard error stream.
所以他们的实现不符合API.这就是defaultUncaughtExceptionHandler不起作用的原因.
结论
不要使用JavaExecMojo.请改用ExecMojo.例如.
mvn exec:exec -Dexec.executable="java" -Dexec.workingdir="someDir" -Dexec.args="-cp target/classes"
在pom中指定插件属性,您可以使用占位符.例如.
<workingdir>${basedir}</workingdir>
<args>-cp ${project.build.outputDirectory}</args>
内容总结
以上是互联网集市为您收集整理的java – setUncaughtExceptionHandler在Maven项目中不起作用全部内容,希望文章能够帮你解决java – setUncaughtExceptionHandler在Maven项目中不起作用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。