Unexpected NoSuchMethodError RowMetadata.getColumnMetadatas() - In spite of correct dependencies - spring-data

When running my application (Spring Boot 2.5.7) - after updating to spring-data-r2dbc 1.3.7, I get the NoSuchMethodError RowMetadata.getColumnMetadatas().
(I have also tried this with 1.4.0 - 1.3.7 is where the problem first surfaces.)
In this spring-data-r2dbc release, a change has been made to move off of getColumnNames (See https://github.com/spring-projects/spring-data-r2dbc/issues/683) to getColumnMetaDatas().
What is odd is that I also have the dependencies
r2dbc-spi - 0.9.0.RELEASE
org.postgresql:r2dbc-postgresql - 0.9.0.RC1
The 0.9.0 RC1 of r2dbc-postgresql fulfills the spi contract. So, it seems that everything should be in place -
The correct version of spring-data-r2dbc (1.3.7) invokes 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.
I have looked at my maven dependency tree and see no competing versions of any of these.
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. 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:
[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
Updated my JDK to the latest version of Corretto 1.8
Compiled spring-data-r2dbc 1.4.0 with that version and used it
Inserted code in RowMetaDataUtils to reflect and log the methods found in the metadata parameter of containsColumn(...). The results include public java.util.List<io.r2dbc.postgresql.PostgresqlColumnMetadata> io.r2dbc.postgresql.PostgresqlRowMetadata.getColumnMetadatas(), which makes this even more perplexing.
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
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.
This is the signature of the 0.8.5 release of r2dbc-spi. In later versions, this has been changed to return a list which would be resolved to the appropriate method in 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.

Related

Exception on executing ext:news upgrade wizard for updating path_segment in TYPO3 9

After upgrading to TYPO3 9, some of the tx_news_domain_model_news path_segment fields were empty, so I marked Upgrade Wizard
"Updates slug field "path_segment" of EXT:news records" of news extension" as undone and tried to execute it. This throws an exception. Makes no difference if executed via backend or on command line, though the command line shows a success message before the error::
typo3-cli upgrade:run newsSlug
Output:
In UpgradeWizardsService.php line 466:
No valid wizard identifier given
in /var/www/domain/htdocs/typo3_src-9.5.5/typo3/sysext/install/Classes/Service/UpgradeWizardsService.php line 466
*/
protected function assertIdentifierIsValid(string $identifier): void
{
if ($identifier === '' || (!isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][$identifier]) && !is_subclass_of($identifier, RowUpdaterInterface::class))) {
throw new \RuntimeException('No valid wizard identifier given', 1502721731);
}
}
}
Current TYPO3 version 9.5.5.
There are changelog entries:
Deprecation: #86366 - Methods in AbstractUpdate
Feature: #86076 - New API for UpgradeWizards
There is a new Interface for upgrade wizard, but as far as I understand it, the "old" update wizards with AbstractUpdate should still work in 9.x.
Is this a bug? I've got the original problem solved, because the update wizard did successfully convert the entries (see original question).
I'd just like to have clarification for implementation of update wizards in TYPO3 9.
Yes this was a bug in the news extension and fixed in master. Be aware that the implementation of update wizards changed in 9 a bit, therefore also this bug occurred.

Grails afterInsert hook issue with Hibernate 5.1 and PostgreSQL

In an existing Grails 3.1.15 application, recently upgraded to Hibernate 5.1, an odd issue with afterInsert (or other) hooks started to appear. After some hours of testing, I could track this down to Hibernate 5.1 + PostgreSQL combination - issue is not reproducible with H2. To reproduce, create a simple application consisting of 2 domain objects - an Audit trail and a User, as shown here:
class Audit {
Date dateCreated
String auditData
}
class User {
String name
String email
def afterInsert() {
new Audit(auditData: "User created: $this").save()
}
}
The code above works OK with Hibernate 4, however, if the application is upgraded to Hibernate5 plugin + Hibernate 5.1.x (tested with 5.1.0.Final and 5.1.5.Final) the above scenario will always lead to a ConcurrentModificationException when you attempt to save a new User instance. You can just use a scaffold controller to reproduce. Note this only happens with PostgreSQL as the data source - with H2 it would still work OK.
Now, according to GORM Docs (see chapter 8.1.3) one should use a new session when attempting to save other objects in beforeUpdate or afterInsert hooks anyway:
def afterInsert() {
Audit.withNewSession() {
new Audit(auditData: "User created: $this").save()
/* no exception logged, but Audit instance not preserved */
}
}
But this wouldn't really resolve the issue with PSQL. The exception is gone, the User instance is persisted, but the Audit instance is not saved. Again, this code would work OK with H2. To really avoid the issue with PSQL, you would have to manually flush the session in afterInsert:
def afterInsert() {
Audit.withNewSession() { session ->
new Audit(auditData: "User created: $this").save()
session.flush()
/* finally no exceptions, both User and Audit saved */
}
}
Question: is this a bug, or is this expected? I find it a bit suspicious that the manual flush is required in order for the Audit instance to be persisted - and even more so when I see it works without a flush with H2 and only seems to affect PostgreSQL. But I couldn't really find any reports - any pointers are appreciated!
For the sake of completeness, I tested with the following JDBC driver versions for PostgreSQL:
runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
runtime 'org.postgresql:postgresql:9.4.1208.jre7'
runtime 'org.postgresql:postgresql:42.0.0'
And for the upgrade to Hibernate 5.1, the following dependencies were used:
classpath "org.grails.plugins:hibernate5:5.0.13"
...
compile "org.grails.plugins:hibernate5:5.0.13"
compile "org.hibernate:hibernate-core:5.1.5.Final"
compile "org.hibernate:hibernate-ehcache:5.1.5.Final"

TFS Server plugin fails after upgrade from TFS2012 to TFS2015 RC

We have just upgraded one of our servers from TFS2012.2 to TFS2015RC. Everything went "smooth", but we are encountering an issue:
A while ago we wrote a server side plugin for TFS, which listens to the WorkitemChangedEvent. It implements the ISubscriber interface. The following piece of code was working fine before the update:
void ITfsService.UpdateState(int workItemId, string newState)
{
var wi = store.GetWorkItem(workItemId);
wi.State = newState;
wi.Save();
}
After the update, and after recompiling against the TFS2015 dlls, the following error occured:
Failed to process notification: TF237124: Work Item is not ready to save.
Note that none of the workitemtypes has changed, it is the same data.
I tried getting more information out of the error by calling Validate() before saving, this is the output:
Status: InvalidListValue
State: "Resolved, To Be Reviewed"
WIT: Task
Id: 5842
Field: State
However, the state "Resolved, To Be Reviewed" does exists in the list of available states. In the GUI it is perfectly possible to change the state of the item to "Resolved, To Be Reviewed":
What is causing the Save() to fail?
Finally found the cause of this:
Apparently, the Validate() call validates against the whole ProcessConfiguration.xml. Because in TFS2012 there were both AgileProcessConfiguration and CommonProcessConfiguration, there were underlying problems with the workitem states.
After resolving those issues in the correct ProcessConfiguration file, the plugin was working again (and, TFS could also upgrade the Backlog\IterationPlanning features.)

NoClassDefFoundError in openid4java

I have downloaded openid4java-0.9.6.662 and implemented a class using it. When I execute:
List discoveries = manager.discover("https://www.google.com/accounts/o8/id");
I get a
java.lang.NoClassDefFoundError: org/apache/http/protocol/ImmutableHttpProcessor
at org.apache.http.impl.client.AbstractHttpClient.getProtocolProcessor(AbstractHttpClient.java:656)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:804)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at org.openid4java.util.HttpCache.head(HttpCache.java:335)
at org.openid4java.discovery.yadis.YadisResolver.retrieveXrdsLocation(YadisResolver.java:400)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:248)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:232)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:166)
at org.openid4java.discovery.Discovery.discover(Discovery.java:147)
at org.openid4java.discovery.Discovery.discover(Discovery.java:129)
at org.openid4java.consumer.ConsumerManager.discover(ConsumerManager.java:542)
at com.sugra.openid.helper.OpenIDConsumer.authRequest(OpenIDConsumer.java:90)
the funny thing is this class cannot be found in any of the jars, thought it is supposed to be found in httpcore-4.0.1.jar, as it contains classes of the same package. This class is available in httpcore-4.2.1.jar. But I've tried it and got
org.openid4java.discovery.yadis.YadisException: 0x704: I/O transport error: hostname in certificate didn't match: <www.google.com/173.194.35.144> != <www.google.com>
that is reported to be an error of portability and a previous version should be used
What is supposed to be the right approach to use this method?
I found it. There was a conflict with another jar (httpclient.jar) I had in my app. I just had to upgrade it

Undefined method `FactoryGirl' -- upgrading from 2.0.2 to 3.4.2

I'm in the process of upgrading from factory_girl (2.0.2 to 3.4.2) and factory_girl_rails (1.1.0 -> 3.4.0)
and I'm having issues with my rspec tests seeing factory girl.
I think I've successfully altered my factories to deal with the new syntax, and have removed the extra require statements that were bringing in multiple copies of the same files. My server now starts up, so I know that the factories.rb file is correctly getting parsed.
Now when I run my rspec tests, I'm getting this error:
NoMethodError: undefined method `FactoryGirl' for #
it 'can be created' do
course = FactoryGirl(:course)
….
end
With Factory Girl 3.4.2, you will need to explicitly use the create method.
course = FactoryGirl.create(:course)