grails应用程序因init

时间:2017-01-10 02:38:58

标签: spring exception grails groovy application-shutdown

我有一个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更多

我在寻找的是:

  1. 为什么会这样?
  2. 我可以采取哪些措施来解决此问题
  3. 如果我无法修复现有代码,那么解决方法是什么?我尝试过的解决方法:在扩展InitializingBean之后使用PostContext注释和afterPropertiesSet方法。这两个解决方案不起作用,因为我使用的init代码最终将使用GORM,因此GORM必须在代码运行时运行。在这两个钩子中,GORM没有准备好(或者说错误消息说明了。)
  4. 我正在使用grails 2.4.5。

    还有一件事:除了你上面看到的代码之外,我已经删除了init中的所有代码,所以我很确定这些REST调用获得异常直接导致应用程序关闭。

    任何帮助非常感谢。谢谢!

0 个答案:

没有答案
相关问题