bigbone icon indicating copy to clipboard operation
bigbone copied to clipboard

`AbstractMethodError` at `MastodonClient.build()`

Open McPringle opened this issue 11 months ago • 12 comments

My project apus was working fine for about a year but since today it broke with the following exception when it calls new MastodonClient.Builder("mastodon.social").build():

java.lang.AbstractMethodError: Receiver class social.bigbone.nodeinfo.entity.Server$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
	at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
	at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
	at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
	at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:937)
	at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
	at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
	at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
	at kotlinx.serialization.json.internal.JsonNamesMapKt.getJsonNameIndexSlowPath(JsonNamesMap.kt:73)
	at kotlinx.serialization.json.internal.JsonNamesMapKt.getJsonNameIndex(JsonNamesMap.kt:97)
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeObjectIndex(StreamingJsonDecoder.kt:229)
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeElementIndex(StreamingJsonDecoder.kt:178)
	at social.bigbone.nodeinfo.entity.Server$$serializer.deserialize(Server.kt:11)
	at social.bigbone.nodeinfo.entity.Server$$serializer.deserialize(Server.kt:11)
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
	at kotlinx.serialization.internal.NullableSerializer.deserialize(NullableSerializer.kt:30)
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
	at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
	at social.bigbone.nodeinfo.NodeInfoClient.retrieveServerInfo(NodeInfoClient.kt:90)
	at social.bigbone.MastodonClient$Builder.getInstanceVersion(MastodonClient.kt:971)
	at social.bigbone.MastodonClient$Builder.build(MastodonClient.kt:1038)
	at swiss.fihlon.apus.MastodonTest.showPosts(MastodonTest.java:17)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1460)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2036)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)

How to reproduce:

  1. git clone https://github.com/McPringle/apus.git
  2. cd apus
  3. git checkout 332f323f339a5c2125657a78c6b0244d39f8af0a
  4. ./mvnw test -Dtest=swiss.fihlon.apus.MastodonTest

I wrote the test MastodonTest just to reproduce this error with as less code as possible. This is how the test class looks like:

public class MastodonTest {

    @Test
    void showPosts() throws BigBoneRequestException {
        final MastodonClient client = new MastodonClient.Builder("mastodon.social").build(); // AbstractMethodError
        final Range range = new Range(null, null, null, 10);
        final List<Status> posts = client.timelines().getTagTimeline("java", LOCAL_AND_REMOTE, range).execute().getPart();
        System.out.println(posts);
    }

}

Here are the two relevant snippets from the pom.xml:

        <!-- Enable snapshots to use BigBone Mastodon client API -->
        <repository>
            <id>maven-central-snapshots</id>
            <name>Maven Central Snapshot Repository</name>
            <url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <dependency>
            <groupId>social.bigbone</groupId>
            <artifactId>bigbone</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>

This project requires Java 21 or newer.

Fun fact: Two days ago it was working fine and I have no idea why this error shows up... 😜

McPringle avatar Feb 07 '25 13:02 McPringle

There has been a new 2.0.0-SNAPSHOT release with some changes to the NodeInfoClient, which is probably why that error shows up for you now. I can't reproduce the error using your example code while building the library from scratch, though - and the AbstractMethodError documentation claims that "this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled".

I believe changes to SNAPSHOT releases are sometimes not properly detected, so could this just be a problem with an outdated cache or partial incremental build on your end?

bocops avatar Feb 07 '25 15:02 bocops

I did a clean on the build and deleted the complete ~/.m2 directory. After some research with friends we have the suspicion that has to do with transitive Kotlin dependencies.

Image

kotlin-stdlib-jdk8 as a transitive dependency via okhttp3 vs. kotlin-stdlib as a dependency of BigBone.

Have you tried to reproduce using my four steps mentioned in the issue? If I create a plain project with BigBone as the only dependency, it works. If I use it in my project, it does not work. If I change the version of BigBone to 2.0.0-20240518.212224-30 (the previous one) it works fine with my project.

McPringle avatar Feb 07 '25 17:02 McPringle

@McPringle I now reproduced with your project.

Comparing our two snapshot releases, among other things we updated our dependency on org.jetbrains.kotlinx:kotlinx-serialization-json from 1.6.3 in the last to 1.8.0 in the current snapshot - and I can get the same error, both using your example as a BigBone sample as well as via several tests failing during a build, by just lowering the version to anything below 1.8.0 (including the previous 1.7.3).

In every case, the AbstractMethodError points to a non-existing method typeParametersSerializers() for one of our entities. I currently don't quite know what to make of that.

bocops avatar Feb 10 '25 14:02 bocops

Thank you very much for reproducing my problem. Actually it does not hurry. In my project I do only a call to get public posts of a specific hashtag to show them on screen (it is a social wall), so I replaced the call to the BigBone library with a direct call to the REST endpoint and parse the JSON myself.

I'm preparing the wall for the Voxxed Days Zürich conference on March 25th and JavaLand conference on April 1st to 3rd and don't want to take any risk. 😅

McPringle avatar Feb 10 '25 15:02 McPringle

I believe this problem was ultimately caused by incompatibilities between two of our 2.0.0-SNAPSHOT releases, and could have been avoided by depending on a stable release or at least a uniquely named pre-release version, neither of which currently exists.

@andregasser I suggest to eventually release a 2.0.0 - or at least 2.0.0-rc1, although that might be overkill at this point - and close this as WONTFIX.

bocops avatar Mar 14 '25 10:03 bocops

Hi, does this issue still perstist? We use the 2.0.0 Snapshot release, but we run against it. Is there anything we do to make this work?

grobmeier avatar Apr 29 '25 15:04 grobmeier

From looking at https://github.com/Kotlin/kotlinx.serialization/issues/2968, I understand what we’re seeing as an incompatibility between different versions of kotlinx-serialization being mixed.

You could try adding the freeCompilerArgs as described by @sandwwraith

kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xjvm-default=all-compatibility")
    }
}

to your build.gradle.kts.

If that works, we could potentially add that to the library.

You could also try enforcing the same kotlinx-serialization version using gradle’s Resolution rules.

Have you tried to reproduce using my four steps mentioned in the issue? I have not yet done that so I cannot say if either of the two when added to a project using BigBone would fix the issue.

PattaFeuFeu avatar Apr 29 '25 18:04 PattaFeuFeu

I have this problem in one of my Java applications. Is it possible to solve this issue on my side or do the compilerOptions have to be added in the bigbone library?

seism0saurus avatar May 11 '25 19:05 seism0saurus

@seism0saurus Please try if the compilerOptions approach in your app works

PattaFeuFeu avatar May 12 '25 06:05 PattaFeuFeu

I just tried rebuilding bigbone from source, using the compilerOptions bit, and my Java application using bigbone still experiences this same error. Just FYI.

I also tried pinning the kotlinx-serialization-json dependency to 1.8.1. Tried that two different ways, but no joy with that either.

build.gradle.kts

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
}

kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xjvm-default=all-compatibility")
    }
}

and

build.gradle.kts

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") {
        version {
            strictly('1.8.1')
        }
    }
}

kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xjvm-default=all-compatibility")
    }
}

mindcrime avatar Jun 07 '25 20:06 mindcrime

Hey all, good news. I got this to work!

The bad news... I made so many changes, both in my build of bigbone, and in my client code, that now I'm not exactly sure what changes are needed and which ones aren't. It's going to take me a while to back out all the changes I made and re-test everything probably.

But I can say this: the last change I made was in my pom for my client code. I noticed that in the error messages I was getting, I was seeing a reference to kotlinx-serialization-core-jvm version 1.6.3. So I added an explicit dependency for that with version 1.8.0 (to match what I I was using everywhere else) and lo and behold, it worked. It seems that Spring boot was pulling in that library as a transitive dependency with the older version. In hindsight, I'm not sure I needed to make any changes to bigbone at all.

I'll revert my pom back to use the official 2.0.0-SNAPSHOT from the Sonatype repo and see what happens. If that works, that will show that, at least for me, all of the problems were purely on the client and nothing to do with the library itself. Give me a bit and I'll run that test and report back.

mindcrime avatar Jun 07 '25 22:06 mindcrime

OK, so for what it's worth, at least for me, everything came down to issues about transitive dependencies in my client code. I went back to pulling the current 2.0.0-SNAPSHOT of Bigbone from the repo and everything works now. I'm building my client with Maven, and here's what the relevant portion of my pom.xml looks like, in case this helps anybody else:

        <dependency>
            <groupId>social.bigbone</groupId>
            <artifactId>bigbone</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>
        
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.12.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.jetbrains.kotlinx</groupId>
            <artifactId>kotlinx-serialization-json-jvm</artifactId>
            <version>1.8.0</version>
        </dependency>
       
       <dependency>
         <groupId>org.jetbrains.kotlinx</groupId>
         <artifactId>kotlinx-serialization-core-jvm</artifactId>
         <version>1.8.0</version>
       </dependency>

mindcrime avatar Jun 07 '25 22:06 mindcrime