Troubleshooting record: how to resolve the spring-boot project started jamming

Background problem

A spring boot development projects, spring boot version is 1.5.7, spring version is 4.1.3 carry. Development feedback, suddenly not start up locally, appearance feature is running on the local IDEA, the process does not quit stuck, load related components when the application starts log is not output. FIG symptoms are as follows:

img

problem analysis

Because there is no useful log information, so you can not troubleshoot log on from this level. But not like this, then the output log, under normal circumstances, is certainly an internal program to start somewhere stuck in the process, only through the next print information for current thread stack next. In general, in a server environment, we will use the java toolkit jstack tool to see: as jstack pid (java application process).

However, if the development of the local IDEA, IDEA built a tool that can be viewed directly on the thread line text information about the current application, such as:

img

Note below the arrow pointing to the camera like the same icon, so Tooth Italy, is a snapshot of the current thread print means. After clicking, it appeared that the right thread context information, you can see there are a lot of thread, our main concern at the main thread, the thread state is indeed waiting, and then click the arrow is pointing to the main thread, you can see the following:

"main@1" prio=5 tid=0x1 nid=NA waiting
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
at org.springframework.boot.autoconfigure.BackgroundPreinitializer.onApplicationEvent(BackgroundPreinitializer.java:63)
at org.springframework.boot.autoconfigure.BackgroundPreinitializer.onApplicationEvent(BackgroundPreinitializer.java:45)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:158)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.finished(EventPublishingRunListener.java:115)
at org.springframework.boot.SpringApplicationRunListeners.callFinishedListener(SpringApplicationRunListeners.java:79)
at org.springframework.boot.SpringApplicationRunListeners.finished(SpringApplicationRunListeners.java:72)
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:745)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
- locked <0xea6> (a java.util.concurrent.atomic.AtomicBoolean)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:175)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:98)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:64)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:325)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
at cn.keking.project.customerManagement.KekingCustomerManagement.main(KekingCustomerManagement.java:36)

It can be seen by CountDownLatch.await () blocks the thread, then look below the line, where the code block as follows:

private static final CountDownLatch preinitializationComplete = new CountDownLatch(1);
 
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
   if (event instanceof ApplicationEnvironmentPreparedEvent) {
      if (preinitializationStarted.compareAndSet(false, true)) {
         performPreinitialization();
      }
   }
   if (event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) {
      try {
         preinitializationComplete.await();
      }
      catch (InterruptedException ex) {
         Thread.currentThread().interrupt();
      }
   }
}

This is a class a secure initialization resources of spring boot in, to listen SpringApplicationEvent event shown in the code, to be sure, it's logical to perform a preinitializationComplete.await (); here, leading to a thread blocked. Under normal circumstances, spring events will trigger ApplicationEnvironmentPreparedEvent complete resource initialization, where the first does not go into why the Spring to do so, mainly through the program logic look at why the card here, in preinitializationComplete.await (); row to make a break, look event objects inside information, as follows:

img

原来event是一个Spring上下文初始化失败的异常事件对象,对象里包含了具体的异常信息,如箭头所指,关键异常信息如:

NoSuchMethodError:"org.springframework.util.ObjectUtils.unwrapOptional(Ljava/lang/Object;)Ljava/lang/Object;"

假设问题

通过上面的分析,基本定位到Spring boot应用启动卡住这个表象背后的真实原因了,而且也定位到了异常信息。

出现NoSuchMethodError异常,是因为调用方法的时候,找不到方法了。一般出现在两个有关联的jar包,但是版本对不上了,也就是常说的jar版本依赖冲突。查看了下,ObjectUtils是spring-core包里的一个类,当前的4.1.3版本确实没有这个unwrapOptional方法,spring-core-5.x的版本才新增了这个方法。因为之前的依赖是没有问题,为什么现在spring上下文会调用5.x的版本的方法呢?

所以先假设近期有开发在pom.xml里添加了新的的依赖,导致了这个问题。

小心求证

有了找问题的方向就好办了,因为代码都是git管理维护的,所以查看下pom.xml文件近期的提交记录即可,查看后,确实发现了近期对pom.xml有改动,添加了一个依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.6.RELEASE</version>
</dependency>

Here also involves a little Maven relies priority issues, such added directly dependent on pom.xml in preference to other jar in pom.xml dependency, that is to say, even if the spring boot1.5.7 comes with Spring-context.4.1 .3, but such a designation, the application of the final version still relies 5.1.6. Specific Maven dependencies, you can refer to my blog "on the use of Maven, which is something you understand it? " . Before the binding assay, pretty close is because of the increase caused by this problem dependent, spring-context.5.1.6 with spring-core.4.1.3 certainly draw the problem ah. Simply remove the dependency, and then start the system as usual, print the log information on Spring loaded line text.

summary of the issue

The key problem is to locate the knowledge of the java thread stack, in the absence of sufficient abnormal situation by threading a snapshot log to troubleshoot the problem. After positioning problems, such as abnormal NoSuchMethodError, usually need experience to assume that the real cause of the problem, then bent over backwards to verify that the root cause of the problem. Be sure to find the essence of the problem this progressive thinking. For example, this problem, if you go directly to the search engines search: "Spring boot application launch stuck" is not found out anything, but when you find a jar because of the conflict. Go to the search engine:

"NoSuchMethodError:" org.springframework.util.ObjectUtils.unwrapOptional (Ljava / lang / Object;) Ljava / lang / Object; "". There will be a lot of content, it is easy to solve the problem.

Published 107 original articles · won praise 14 · views 40000 +

Guess you like

Origin blog.csdn.net/belongtocode/article/details/103383096