我正在使用here中的代码来重新启动Spring Boot应用程序:
Thread restartThread = new Thread(() -> restartEndpoint.restart());
restartThread.setDaemon(false);
restartThread.start();
但是,重新启动的应用程序无法创建Bean,最终是由于尝试安排带有 RejectedExecutionException
注释的方法时抛出了@Scheduled
:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean' defined in URL [insert-path-here]: Initializetion of bean failed; nested exception is org.springframework.core.TaskRejectedException: Executor [java.util.concurrent.ScheduledThreadPoolExecutor@284a4a89[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 21508]] did not accept task: my.package.MyBean.scheduledMethod
令人尴尬的是,事实证明doRestart()
调用之后的日志表明ExecutorService taskScheduler
正在关闭,这可以解释为什么会发生这种情况。我不确定的是为什么不重新创建ExecutorService。taskScheduler
是我的应用程序定义的bean,没有注释@RefreshScope
。现在我得到的错误是
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'anotherBean' definen in URL[...]: Unsatisfied dependency expressed through constructor parameter 0 ... nested exception is java.lang.IllegalStateException: org.springframework.boot.servlet.context.AnnotationConfigServletWebServerApplicationContext@2a95076c has been closed already
在日志中向上滚动会发现有一个ApplicationContextException
与包含doRestart
的堆栈跟踪一起抛出:
org.springframework.ApplicationContextException: Unable to start web server; nested exception is java.lang.IllegalStateException: Filters cannot be added to context [/myapp] as the context has been initialized
at org.springframework.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:157)
...
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.cloud.context.restart.RestartEndpoint(RestartEndpoint.java:160)
at my.package.MyBean.lambda$doThingAndRestart$2 (MyBean.java: 118)
搜索该错误似乎会导致single page无关紧要,尽管我确实注意到该应用程序也在Tomcat上运行。
我怀疑这与应用程序创建错误的应用程序上下文有关,该上下文是AnnotationConfigServletWebServerApplicationContext
,没有扩展AbstractRefreshableAplicationContext。
我该怎么办才能消除此错误?
当我仅从堆栈跟踪中复制单行时,请忍受我。我使用的是两台计算机,因此无法复制和粘贴,也不允许将日志移动到连接到Internet的计算机上。
答案 0 :(得分:0)
事实证明,RestartEndpoint
仅适用于Spring的内部Tomcat,不适用于外部的Tomcat。因此,需要另一种解决方案。我发现的是
doThingAndRestart
功能时需要维护Tomcat配置。reload
请求一直阻塞,直到应用程序完成重新加载为止,这使堆空间溢出。