背景問題
春ブーツ開発プロジェクト、春のブートバージョンは1.5.7で、春のバージョンは4.1.3キャリーです。アプリケーションは、ログが出力されていない起動時に開発のフィードバックは、突然、プロセスがスタックし、負荷関連のコンポーネントを終了していない外観機能はローカルIDEA上で実行されている、ローカルで起動しません。次のように図の症状は以下のとおりです。
分析
有用なログ情報が存在しないので、あなたはこのレベルからログオントラブルシューティングをすることはできません。しかし、ではない、このように、その後、出力ログは、通常の状況下では、唯一の次の現在のスレッドのスタックのための次の印刷情報を通じて、プロセスのどこかに立ち往生開始する内部プログラムは確かです。jstack PID(javaアプリケーション・プロセス)として:一般的には、サーバー環境では、我々が表示するには、Javaツールキットjstackツールを使用します。
しかし、地元のIDEAの開発場合、IDEAのような、現在のアプリケーションについてのスレッド行のテキスト情報を直接見ることができるツールを構築しました:
歯イタリアそう同じアイコンのようなカメラを指す矢印、下記の注意事項は、現在のスレッドの印刷手段のスナップショットです。クリックした後、右のスレッドコンテキスト情報は、あなたが、あなたは以下を参照してくださいすることができ、スレッドの状態が実際に待機しているスレッドの多くは、メインスレッドで私たちの主な懸念がある参照して、矢印がメインスレッドを指しているクリックできると思われました。
"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)
それはCountDownLatch.await()ブロックのスレッドによって見ることができる、コードブロックは次のように行の下に見えます。
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();
}
}
}
ブロックされたスレッドにつながる、ここでは、これは確かに、コードに示すSpringApplicationEventイベントを聞くために、クラスの春ブーツの安全な初期化資源である、それはpreinitializationComplete.awaitを()を実行するために論理的です。通常の状況下では、春のイベントは、最初preinitializationComplete.await()で、ここでは主に、なぜカードでのプログラムロジックを見て、春がそうする理由にはなりませんApplicationEnvironmentPreparedEvent完全なリソースの初期化を、トリガされます。行をブレーク、外観を作るために次のようにイベントは、内部情報をオブジェクト:
原来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>
ここにも少しのMavenは、春のboot1.5.7は春context.4.1が付属していても、言うことです優先課題、のpom.xml依存関係にある他の瓶に優先してのpom.xmlにそのような追加直接的に依存し、依存関係.3、そのような指定は、最終バージョンのアプリケーションは、まだ5.1.6に依存しています。特定のMavenの依存関係は、あなたが私のブログを参照することができ、あなたがそれを理解する何かであるのMavenの使用について」、?"。結合アッセイの前に、かなり近いので、確かに問題がああを描く春-core.4.1.3で、この問題に依存し、春-context.5.1.6によって引き起こさ増加です。単に依存関係を削除した後、いつものように、システムを起動し、春ロードされた行のテキストのログ情報を印刷します。
問題の概要
重要な問題は、問題を解決するためにスナップショット・ログをねじ込むことによって、十分な異常な状況が存在しない場合に、Javaスレッド・スタックの知識を見つけることです。このような異常NoSuchMethodErrorなどの問題を、位置決めした後、通常は必要な経験、そして、問題の根本原因ことを確認するために、後方に曲がって、問題の本当の原因と仮定すること。問題この進歩的思考の本質を見つけてください。あなたが検索エンジンに直接行く場合たとえば、この問題は、検索:何かを見つけたが、ときに競合が原因の瓶を発見されていない「春のブートアプリケーションの起動を立ち往生」。検索エンジンに移動します:
"NoSuchMethodError:" org.springframework.util.ObjectUtils.unwrapOptional(Ljava /ラング/オブジェクト;)Ljava /ラング/オブジェクト ";"。問題を解決するために簡単ですが、多くのコンテンツがあります。