简体   繁体   English

意外的 NoSuchMethodError RowMetadata.getColumnMetadatas() - 尽管存在正确的依赖关系

[英]Unexpected NoSuchMethodError RowMetadata.getColumnMetadatas() - In spite of correct dependencies

When running my application (Spring Boot 2.5.7) - after updating to spring-data-r2dbc 1.3.7, I get the NoSuchMethodError RowMetadata.getColumnMetadatas() .运行我的应用程序(Spring Boot 2.5.7)时 - 更新到 spring-data-r2dbc 1.3.7 后,我得到NoSuchMethodError RowMetadata.getColumnMetadatas()

(I have also tried this with 1.4.0 - 1.3.7 is where the problem first surfaces.) (我也尝试过 1.4.0 - 1.3.7 是问题首先出现的地方。)

In this spring-data-r2dbc release, a change has been made to move off of getColumnNames (Seehttps://github.com/spring-projects/spring-data-r2dbc/issues/683 ) to getColumnMetaDatas() .在此 spring-data-r2dbc 版本中,已将getColumnNames (参见https://github.com/spring-projects/spring-data-r2dbc/issues/683 )更改为getColumnMetaDatas()

What is odd is that I also have the dependencies奇怪的是我也有依赖

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

The 0.9.0 RC1 of r2dbc-postgresql fulfills the spi contract. r2dbc-postgresql 的 0.9.0 RC1 履行了 spi 合约。 So, it seems that everything should be in place -所以,似乎一切都应该到位——

The correct version of spring-data-r2dbc (1.3.7) invokes getColumnMetaDatas() : 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;
    }

which is a method of the 0.0.9.RELEASE r2dbc-spi interface RowMetaData , which is fulfilled by the 0.9.0.RC1 version of r2dbc-postgresql PostgresqlRowMetadata .这是 0.0.9.RELEASE r2dbc-spi 接口RowMetaData的一个方法,由 r2dbc-postgresql PostgresqlRowMetadata的 0.9.0.RC1 版本实现。

I have looked at my maven dependency tree and see no competing versions of any of these.我查看了我的 maven 依赖树,并没有看到其中任何一个的竞争版本。

I could assume that the binding of the implementation to the spi is bad, but I got far enough to make the call to the database and then try to extract the data, so that doesn't seem right.我可以假设实现与 spi 的绑定很糟糕,但我已经足够远了,可以调用数据库然后尝试提取数据,所以这似乎不对。 So, it appears that something else is off.因此,似乎还有其他事情发生了。

I added the command line option -verbose:class to see what classes/jars are being loaded and things look correct from there as well:我添加了命令行选项-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

Stack Trace:堆栈跟踪:

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(...

I've also我也有

  1. Updated my JDK to the latest version of Corretto 1.8将我的 JDK 更新到最新版本的 Corretto 1.8
  2. Compiled spring-data-r2dbc 1.4.0 with that version and used it使用该版本编译 spring-data-r2dbc 1.4.0 并使用它
  3. Inserted code in RowMetaDataUtils to reflect and log the methods found in the metadata parameter of containsColumn(...) .在 RowMetaDataUtils 中插入代码以反映和记录在containsColumn(...)metadata参数中找到的方法。 The results include public java.util.List<io.r2dbc.postgresql.PostgresqlColumnMetadata> io.r2dbc.postgresql.PostgresqlRowMetadata.getColumnMetadatas() , which makes this even more perplexing. The results include public java.util.List<io.r2dbc.postgresql.PostgresqlColumnMetadata> io.r2dbc.postgresql.PostgresqlRowMetadata.getColumnMetadatas() , which makes this even more perplexing.

One possibility may be found in the error:在错误中可能会发现一种可能性:

java.lang.NoSuchMethodError: 
io.r2dbc.spi.RowMetadata.getColumnMetadatas()Ljava/lang/Iterable;

where the method getColumnMetadatas() found returns a java.util.List<io.r2dbc.postgresql.PostgresqlColumnMetadata> .找到的方法 getColumnMetadatas() 返回java.util.List<io.r2dbc.postgresql.PostgresqlColumnMetadata> Since a List is an Iterable , it would seem fine.由于ListIterable ,因此看起来不错。 But perhaps there's something else going on...?但也许还有其他事情正在发生......?

I'll try and get a test that duplicates this - but hope that somebody has an idea for me to try to fix or debug with.我会尝试做一个重复这个的测试 - 但希望有人有一个想法让我尝试修复或调试。

I've finally had time to come back to this.我终于有时间回到这个话题了。 Looking at the byte code for RowMetadataUtils , we see查看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

In this we see that we are looking for an interface method RowMetadata.getColumnMetadatas that returns an iterator.在此我们看到我们正在寻找一个返回迭代器的接口方法RowMetadata.getColumnMetadatas
This is the signature of the 0.8.5 release of r2dbc-spi.这是 r2dbc-spi 0.8.5 版本的签名。 In later versions, this has been changed to return a list which would be resolved to the appropriate method in r2dbc-postgresql.在以后的版本中,这已更改为返回一个列表,该列表将解析为 r2dbc-postgresql 中的适当方法。 So, the 1.4.0 release of spring-data-r2dbc should be compiled against the 0.0.9.RELEASE version of r2dbc-spi.因此,spring-data-r2dbc 的 1.4.0 版本应该针对 r2dbc-spi 的 0.0.9.RELEASE 版本进行编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM