
解决Intellij IDEA升级2020.3之后无法启动Elasticsearch工程的问题
真的是懒出翔…… 又一年没更新博客了。最近找到了一个水文素材,就赶紧po一下,不要让博客的2020变这么惨QwQ
问题内容
读了一个多月Elasticsearch源码,各种断点调试+环境配置已经顺利至今,突然今天Elasticsearch无法启动了,抛出如下异常:
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.plugins.ExtendedPluginsClassLoader
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
我寻思这不是刚开始调试的时候遇到的classpath问题嘛?(虽然和JVM斗智斗勇了好几年了,至今对Java的classpath规则颇为诟病)
排查过程
既然是classloader出的问题,显然可以推断出当前classpath中没有ExtendedPluginsClassLoader所对应的class文件。Elasticsearch为Gradle项目,自然应该去Elasticsearch启动类Elasticsearch.class所对应server包的build.gradle排查:

找到server包的build.gradle文件,发现如下两行代码:
compileOnly project(‘:libs:elasticsearch-plugin-classloader’)
testRuntimeOnly project(‘:libs:elasticsearch-plugin-classloader’)
蛤?compileOnly,这不是最早运行时处理的问题嘛?原因应该是IDEA默认不会加载Maven provided级别模块的class文件(Maven 中 provided和Gradle的compileOnly特性类似,运行时不会加载)。
记得刚开始搭建环境的时候,参考过这个ISSUE:NoClassDefFoundError: org/elasticsearch/plugins/ExtendedPluginsClassLoader 只需要在IDEA启动选项中勾选加载Maven provided级别的类即可
so我打开IDEA的Debug Configuration,看完傻眼了

天呐这UI怎么变了,然后之前版本的很多选项都不翼而飞了。再寻思这几天我对开发环境唯一的变更就是IDEA升级到了2020.3版本,看来就是这个配置在作妖
解决问题
看到这个界面,我都怀疑IDEA是不是侵犯了谁加知识产权导致启动配置只能简化成上图这些了。但是转念一想毕竟是出了钱的商业软件,而且Elasticsearch这么多开发人员中一定有IDEA重度用户,没准他们有办法,于是Google之:


选定了main classpath,并拉到最下面,勾选Include dependencies with “Provided” scope
Apply Changes之后Elasticsearch工程顺利启动
分锅
这次问题的主要原因还是由于IDEA升级后没有同步相应的Debug启动项配置造成的,再加上IDEA家的UI变更,让我找不到classpath设置选项。还好Stackoverflow中早就有大神发现了这个问题。
也给未来升级IEDA 2020.3的小伙伴踩了一个小坑…… 更新需谨慎(JetBrains退钱!)
建议IDEA以后还是把每年的最后一个稳定版本标记成第二年的EAP吧……不要为了扩大测试样本而把实际的第二年EAP版本标记为今年的最后一个稳定版本呀……
另外我也得加强对Gradle的认知,虽然很排斥Gradle,但好像开源项目从Maven转去Gradle是大势所趋了……