【问题标题】:Unexpected NoSuchMethodError RowMetadata.getColumnMetadatas() - In spite of correct dependenciesUnexpected NoSuchMethodError RowMetadata.getColumnMetadatas() - 尽管存在正确的依赖关系
【发布时间】:2022-01-24 00:31:00
【问题描述】:

运行我的应用程序 (Spring Boot 2.5.7) - 更新到 spring-data-r2dbc 1.3.7 后,我得到 NoSuchMethodError RowMetadata.getColumnMetadatas()

(我也尝试过 1.4.0 - 1.3.7 是问题首先出现的地方。)

在这个 spring-data-r2dbc 版本中,已将 getColumnNames(参见 https://github.com/spring-projects/spring-data-r2dbc/issues/683)更改为 getColumnMetaDatas()

奇怪的是我也有依赖关系

  • r2dbc-spi - 0.9.0.RELEASE
  • org.postgresql:r2dbc-postgresql - 0.9.0.RC1

r2dbc-postgresql 的 0.9.0 RC1 履行了 spi 合约。所以,似乎一切都应该到位 -

spring-data-r2dbc(1.3.7)的正确版本调用getColumnMetaDatas()

public static boolean containsColumn(RowMetadata metadata, String name) {

        for (ColumnMetadata columnMetadata : metadata.getColumnMetadatas()) {
            if (name.equalsIgnoreCase(columnMetadata.getName())) {
                return true;
            }
        }

        return false;
    }

这是0.0.9.RELEASE r2dbc-spi接口RowMetaData的方法,由0.9.0.RC1版本的r2dbc-postgresqlPostgresqlRowMetadata实现。

我查看了我的 maven 依赖树,没有看到任何这些的竞争版本。

我可以假设实现与 spi 的绑定很糟糕,但我已经足够远了,可以调用数据库然后尝试提取数据,所以这似乎不对。因此,似乎还有其他问题。

我添加了命令行选项 -verbose:class 以查看正在加载哪些类/jar,并且从那里看起来也正确:

[30.756s][info][class,load] io.r2dbc.postgresql.message.frontend.CompositeFrontendMessage$$Lambda$2382/0x0000000800ee3840 source: io.r2dbc.postgresql.message.frontend.CompositeFrontendMessage
[30.756s][info][class,load] io.r2dbc.postgresql.message.frontend.Bind$$Lambda$2383/0x0000000800ee3c40 source: io.r2dbc.postgresql.message.frontend.Bind
[30.757s][info][class,load] io.r2dbc.postgresql.message.frontend.Bind$$Lambda$2384/0x0000000800ee4040 source: io.r2dbc.postgresql.message.frontend.Bind
[30.757s][info][class,load] io.r2dbc.postgresql.message.frontend.Bind$$Lambda$2385/0x0000000800ee4440 source: io.r2dbc.postgresql.message.frontend.Bind
[30.761s][info][class,load] io.r2dbc.postgresql.message.backend.ParseComplete source: file:/<removed>/.m2/repository/org/postgresql/r2dbc-postgresql/0.9.0.RC1/r2dbc-postgresql-0.9.0.RC1.jar
[30.762s][info][class,load] org.springframework.data.r2dbc.convert.RowMetadataUtils source: file:/<removed>/.m2/repository/org/springframework/data/spring-data-r2dbc/1.3.7/spring-data-r2dbc-1.3.7.jar

堆栈跟踪:

java.lang.NoSuchMethodError: 
io.r2dbc.spi.RowMetadata.getColumnMetadatas()Ljava/lang/Iterable;
  at org.springframework.data.r2dbc.convert.RowMetadataUtils.containsColumn(RowMetadataUtils.java:38)
  at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.extractGeneratedIdentifier(MappingR2dbcConverter.java:646)
... 2 frames excluded
  at io.r2dbc.postgresql.PostgresqlResult.lambda$map$2(PostgresqlResult.java:123)
  at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(...

我也是

  1. 已将我的 JDK 更新到最新版本的 Corretto 1.8
  2. 用那个版本编译 spring-data-r2dbc 1.4.0 并使用它
  3. 在 RowMetaDataUtils 中插入代码以反映和记录在 containsColumn(...)metadata 参数中找到的方法。结果包括public java.util.List&lt;io.r2dbc.postgresql.PostgresqlColumnMetadata&gt; io.r2dbc.postgresql.PostgresqlRowMetadata.getColumnMetadatas(),这让这更加令人困惑。

我会尝试做一个重复这个的测试 - 但希望有人对我有一个想法来尝试修复或调试。

【问题讨论】:

    标签: spring-data spring-data-r2dbc r2dbc r2dbc-postgresql


    【解决方案1】:

    我终于有时间回到这个话题了。查看RowMetadataUtils 的字节码,我们看到

    public static boolean containsColumn(io.r2dbc.spi.RowMetadata, java.lang.String);
        descriptor: (Lio/r2dbc/spi/RowMetadata;Ljava/lang/String;)Z
        flags: (0x0009) ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=4, args_size=2
             0: aload_0
             1: invokeinterface #2,  1            // InterfaceMethod io/r2dbc/spi/RowMetadata.getColumnMetadatas:()Ljava/lang/Iterable;
             6: invokeinterface #3,  1            // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
            11: astore_2
    

    在此我们看到我们正在寻找一个返回迭代器的接口方法RowMetadata.getColumnMetadatas
    这是 r2dbc-spi 0.8.5 版本的签名。在以后的版本中,这已更改为返回一个列表,该列表将解析为 r2dbc-postgresql 中的适当方法。因此,spring-data-r2dbc 的 1.4.0 版本应该针对 r2dbc-spi 的 0.0.9.RELEASE 版本进行编译。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多