我有一个grails 2.4.5应用程序,它在启动时从bootstrap.groovy运行init闭包。它可能会抛出异常,也可能不会抛出异常,但在任何一种情况下,应用程序都必须继续运行。实际发生的是在init()期间,应用程序无法与服务器通信,底层库抛出SocketTimeoutException,然后由我的代码捕获。捕获的异常意外地导致应用程序调用destroy()并关闭我不想要的应用程序。我预计,由于异常被捕获,因此不应报告任何错误,应用程序应继续运行。
这里是使用RestTemplate库导致应用程序被销毁的代码。没有这个代码,它仍然在运行。捕获并打印异常,然后应用程序关闭。
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
}
}
我认为这与我使用的库(RestTemplate)有关,所以我也尝试使用Unirest库。这也会捕获异常,但会关闭应用程序而不是继续。
init = {
try {
res = Unirest
.post(ME_URL + '/apps/register')
.header('Authorization', auth)
.header('Content-Type', 'application/json')
.body([clientId: CLIENT_ID])
.asObject(Map.class);
} catch (Exception e) {
// don't rethrow
println e.getMessage(); // gets here, app is shutdown
}
}
现在我开始认为可能有异常从init()泄漏,所以我试图手动抛出异常来测试这个理论。我尝试了一个基本的Exception以及前两个库抛出的SocketTimeoutException。这很有趣,因为我已经证明这个例外不会以某种方式泄漏&#34;超出grails初始关闭。下面的代码不会导致应用程序关闭并且它仍然在运行,这就是我想要的。
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的堆栈跟踪,以及我自己的检测代码,以显示destroy()确实被调用。
2017-01-09 12:01:51,825 [localhost-startStop-1] ERROR StackTrace - 完整堆栈跟踪:XXX.YYY.ZZZ.AAA.GatewayException: java.net.SocketTimeoutException:读取超时时间 XXX.YYY.ZZZ.registerApp(GatewayService.groovy:83)at XXX.YYY.ZZZ.initApp(GatewayService.groovy:50)at XXX.YYY.ZZZ.init(GatewayService.groovy:39)at XXX.YYY.ZZZ.slientInit(GatewayService.groovy:30)at XXX.YYY.ZZZ.BBB(Initializer.groovy:88)at BootStrap $ _closure1.doCall(BootStrap.groovy:17)at 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)at 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.UnirestException: java.net.SocketTimeoutException:读取超时时间 com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:143) 在 com.mashape.unirest.request.BaseRequest.asObject(BaseRequest.java:80) 在XXX.YYY.ZZZ.registerApp(GatewayService.groovy:71)... 12更多
我在寻找的是:
我正在使用grails 2.4.5。
还有一件事:除了你上面看到的代码之外,我已经删除了init中的所有代码,所以我很确定这些REST调用获得异常直接导致应用程序关闭。
任何帮助非常感谢。谢谢!