【本地是好的,线上环境报错系列】代码自动生成和版本更新导致的NoSuchMethodError

356 阅读2分钟

事情起因

在开发大模型应用时,需要实现RAG功能,就引入了es作为向量数据库。 pom文件引入:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-elasticsearch-store-spring-boot-starter</artifactId>
</dependency>

下载的依赖中包含:co.elastic.clients:elasticsearch-java:8.13.4,这个依赖项就是出现问题的地方。

报错信息如下:

java.lang.NoSuchMethodError: 'co.elastic.clients.elasticsearch._types.KnnSearch$Builder co.elastic.clients.elasticsearch._types.KnnSearch$Builder.k(java.lang.Integer)'

但是在本地运行时一切正常!

问题排查

进入到这个类中进行查看:

package co.elastic.clients.elasticsearch._types;

//----------------------------------------------------------------
//       THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST.
//----------------------------------------------------------------
//
// This code is generated from the Elasticsearch API specification
// at https://github.com/elastic/elasticsearch-specification
//
// Manual updates to this file will be lost when the code is
// re-generated.
//
// If you find a property that is missing or wrongly typed, please
// open an issue or a PR on the API specification repository.
//
//----------------------------------------------------------------

// typedef: _types.KnnSearch

/**
 *
 * @see <a href="../doc-files/api-spec.html#_types.KnnSearch">API
 *      specification</a>
 */
@JsonpDeserializable
public class KnnSearch implements JsonpSerializable {

报错信息中提示的缺失的方法,在源码中是存在的,为什么会打包后会提示方法不存在呢?

接着,我下载了这个类的源码,其中的注释引起了我的注意,这是通过Elasticsearch API specification自动生成的。

难道打包时,生成的类中不包含这个方法吗?

我没有直接去验证打包后的类中是否包含该方法,我拿着这个注释去问ChatGPT,这是它给的回复:

co.elastic.clients.elasticsearch._types 代码 不是手写的,而是 根据 Elasticsearch API 规范自动生成

根据这个提示,如果API规范变了,那么自动生成时,代码也会变,我按照ChatGPT给的提示,指定了elasticsearch-java的最新版本:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-elasticsearch-store-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.17.1</version>
</dependency>

打包部署后,就恢复了正常。使用了最新的版本后,查看本地的源码,原来报错(NoSuchMethodError)所指的方法已经不存在了。

总结

出现这个问题的原因推测:打包时,使用的最新的APi规范生成了代码,生成的代码中把老版本依赖的方法删除了,导致线上使用的老版本找不到方法的问题。

当不指定版本时,至于为什么打包时会使用最新api规范生成代码,在本地开发时却还是沿用的老版本的规范,这个问题还不清楚,知道的同学可以告知一下。

建议:在引入依赖时,指定版本。

🎯最后

推荐一下开源AI WEB开发框架:X.Ryder 🚀