Spring grails应用程序由于在init中捕获异常而关闭
我有一个Grails2.4.5应用程序,它在启动时从bootstrap.groovy运行init闭包。它可能抛出异常,也可能不抛出异常,但无论哪种情况,应用程序都必须继续运行。实际发生的情况是,在init()期间,应用程序无法与服务器通信,底层库抛出一个SocketTimeoutException,然后被我的代码捕获。捕获到的异常意外地导致应用程序调用destroy()并关闭应用程序,这是我不希望看到的。我希望既然捕获了异常,就不会报告任何错误,应用程序应该保持运行 下面是使用RestTemplate库导致应用程序被销毁的代码。没有这段代码,它仍然在运行。捕获并打印异常,然后关闭应用程序Spring grails应用程序由于在init中捕获异常而关闭,spring,exception,grails,groovy,application-shutdown,Spring,Exception,Grails,Groovy,Application Shutdown,我有一个Grails2.4.5应用程序,它在启动时从bootstrap.groovy运行init闭包。它可能抛出异常,也可能不抛出异常,但无论哪种情况,应用程序都必须继续运行。实际发生的情况是,在init()期间,应用程序无法与服务器通信,底层库抛出一个SocketTimeoutException,然后被我的代码捕获。捕获到的异常意外地导致应用程序调用destroy()并关闭应用程序,这是我不希望看到的。我希望既然捕获了异常,就不会报告任何错误,应用程序应该保持运行 下面是使用RestTempl
init = { servletContext ->
try {
// Send a post request
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", auth);
headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
HttpEntity entity = new HttpEntity(headers);
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectTimeout(10000);
httpRequestFactory.setReadTimeout(10000);
RestTemplate rt = new RestTemplate(httpRequestFactory);
ResponseEntity<String> rtString = rt.exchange(ME_URL + '/apps/register', HttpMethod.POST, entity, String.class);
} catch (Exception e) {
// don't rethrow
println e.getMessage(); // gets here, app is shutdown
}
}
现在我开始认为可能是init()泄漏了异常,所以我试图手动抛出一个异常来测试这个理论。我尝试了一个基本异常以及前两个库抛出的SocketTimeoutException。这很有趣,因为我已经证明这个异常不会以某种方式“泄漏”出grails init闭包。下面的代码不会导致应用程序关闭,它仍在运行,这正是我想要的
init = {
try {
throw new java.net.SocketTimeoutException("fake exception");
} catch (Exception e) {
// don't rethrow
println e.getMessage(); // gets here, but app continues
}
}
通常,错误日志中打印的唯一内容是java.net.SocketTimeoutException的stacktrace,以及我自己的检测代码,以显示确实调用了destroy()
2017-01-09 12:01:51825[localhost-startStop-1]错误堆栈跟踪-
完整堆栈跟踪:XXX.YYY.ZZZ.AAA.GatewayException:
java.net.SocketTimeoutException:读取在时超时
三十、 YYY.ZZZ.registerApp(GatewayService.groovy:83)位于
三十、 YYY.ZZZ.initApp(GatewayService.groovy:50)位于
三十、 YYY.ZZZ.init(GatewayService.groovy:39)位于
三十、 YYY.ZZZ.slientInit(GatewayService.groovy:30)位于
三十、 YYY.ZZZ.BBB(初始化器.groovy:88)位于
BootStrap$\u closure1.doCall(BootStrap.groovy:17)位于
grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:327)
在
grails.util.Environment.executeForEnvironment(Environment.java:320)
在
grails.util.Environment.executeForCurrentEnvironment(Environment.java:296)
在java.util.concurrent.FutureTask.run(FutureTask.java:266)处
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
在
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
在java.lang.Thread.run(Thread.java:745)处,由以下原因引起:
com.mashape.unirest.http.exceptions.unirest异常:
java.net.SocketTimeoutException:读取在时超时
http.HttpClientHelper.request(HttpClientHelper.java:143)
在
com.mashape.unirest.request.BaseRequest.asObject(BaseRequest.java:80)
在XXX.YYY.ZZZ.registerApp(GatewayService.groovy:71)。。。还有12个
我要找的是:
非常感谢您的帮助。谢谢 嗨,我有几个问题:1)我的URL,这是一个独立的服务器吗?2) 当您将超时值增加到更大的值时,例如30秒,您的服务器启动是否会暂停30秒,然后无法初始化?3) 您确定抛出的异常实际上不是一个错误(不是异常的子类,但仍然是可丢弃的)吗?可能用catch(Throwable e)替换catch(Execption e)?1)我的URL当前设置为,我们遇到了这个问题。今天,我发现代码突然起作用了——也就是说,我们捕获了异常,应用程序继续运行。我跟踪到一个开发人员将端口更改为我的计算机上没有运行的端口,因此仍然失败,但出现了HttpHostConnectException。当使用端口8081时,它会失败,因为有一个服务正在侦听该端口,但失败是SocketTimeoutException,它以某种方式(直接或间接)导致应用程序终止,尽管有catch语句。2)超时增加到2分钟,是的,服务器启动会暂停该时间。这是一个阻塞呼叫。然后它捕获异常(当使用端口8081时-请参见#1),但应用程序被销毁。因此,似乎超时不是一个因素3)是的,当然这是一个例外。HttpHostConnectException和SocketTimeoutException。我还试着用脚踢的方式抓住一次性的东西,行为也是一样的@loteqBounty仍然可用-需要找到根本原因,以及如何更改代码(无需进行一些疯狂的奇怪破解)以解决我的问题
init = {
try {
throw new java.net.SocketTimeoutException("fake exception");
} catch (Exception e) {
// don't rethrow
println e.getMessage(); // gets here, but app continues
}
}