You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何对lucene-core进行Shading以兼容ElasticSearch与Solr不同版本

解决ElasticSearch 7.6与Solr 6.6的Lucene版本冲突问题

这种跨组件的核心依赖版本冲突真的很棘手,尤其是Lucene这种底层库,版本差异带来的类结构变化很容易触发NoClassDefFoundError这类随机报错。你尝试的Shading思路是对的,大概率是配置细节没到位,下面给你一套可行的解决方案:

第一步:先理清依赖树

首先用Maven命令确认所有依赖的Lucene版本分布,避免遗漏:

mvn dependency:tree | grep lucene-core

这条命令会列出所有引入lucene-core的依赖,你能清晰看到ES带来的8.4版本和Solr带来的6.6版本分别来自哪些组件。

第二步:正确配置Maven Shade插件

Shading的核心是把Solr依赖的Lucene包重命名为独立的命名空间,避免和ES的Lucene类路径冲突。下面是完整的插件配置,你可以直接加到你的POM的<build><plugins>节点下:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.4.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <!-- 重命名Lucene包到独立命名空间 -->
        <relocations>
          <relocation>
            <pattern>org.apache.lucene</pattern>
            <shadedPattern>shaded.org.apache.lucene</shadedPattern>
            <includes>
              <include>org.apache.lucene.**</include>
            </includes>
            <!-- 排除ES专属的Lucene扩展类,避免干扰 -->
            <excludes>
              <exclude>org.apache.lucene.elasticsearch.**</exclude>
            </excludes>
          </relocation>
        </relocations>
        <!-- 指定只对Solr及其依赖的Lucene进行Shading -->
        <artifactSet>
          <includes>
            <include>org.apache.solr:*</include>
            <include>org.apache.lucene:*</include>
          </includes>
          <excludes>
            <exclude>org.elasticsearch:*</exclude>
          </excludes>
        </artifactSet>
        <!-- 可选:保留原始MANIFEST信息,避免启动类丢失 -->
        <keepManifestFile>true</keepManifestFile>
      </configuration>
    </execution>
  </executions>
</plugin>

关键配置说明:

  • relocation规则:把所有org.apache.lucene开头的类重命名为shaded.org.apache.lucene,这样Solr的代码会调用这个独立命名空间下的Lucene 6.6类,和ES的Lucene 8.4完全隔离。
  • artifactSet过滤:确保只对Solr和它的Lucene依赖进行Shading,ES的组件完全排除在外,避免破坏ES的功能。

第三步:验证Shading结果

执行mvn package打包后,用以下命令检查Jar包内容:

jar tf target/your-project-jar-name.jar | grep shaded/org/apache/lucene

如果能看到大量重命名后的Lucene类,说明Shading成功了。此时运行项目,Solr的代码会优先使用这个独立的Lucene版本,不会再和ES的版本冲突。

备选方案:类加载隔离

如果Shading还是有问题(比如某些反射加载的类没被正确重命名),可以考虑用类加载隔离方案:

  • 把Solr及其Lucene依赖打包成单独的Jar,用自定义类加载器加载这个Jar,和主程序的类加载器隔离。
  • 或者使用OSGi容器(比如Apache Karaf),把ES和Solr分别作为不同的Bundle部署,天然实现类加载隔离。不过这种方案复杂度较高,适合大型项目。

内容的提问来源于stack exchange,提问作者Ryan Mavilia

火山引擎 最新活动