[JAVA-4605] Version 4.6.0 isn't compatible with Java 14 (preview), Java 15 (preview) & Java 16 Created: 05/May/22  Updated: 28/Oct/23  Resolved: 19/May/22

Status: Closed
Project: Java Driver
Component/s: Build
Affects Version/s: 4.6.0
Fix Version/s: 4.6.1

Type: Bug Priority: Minor - P4
Reporter: Juan F. Codagnone Assignee: Ross Lawley
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi,
the language compatibility section states that 4.6 version is compatible with java 11 but when using it in a project with a version < 17 you get

 

java.lang.UnsupportedClassVersionError: org/bson/codecs/record/RecordCodecProvider has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to…)

This happens becase  {{ mongodb-driver-core}} pulls bson-record-codec, and record-codec naturally requires a java 17.

 

 

[INFO] |  +- org.mongodb:mongodb-driver-core:jar:4.6.0:compile
[INFO] |  |  \- org.mongodb:bson-record-codec:jar:4.6.0:runtime

 If bson-record-codec is excluded manually one get into a

 

 

java.lang.NoClassDefFoundError: org/bson/codecs/record/RecordCodecProvider` because the class is loaded while accessing MongoClientSettings.

 

because the codec provided (Jep395RecordCodecProvider) is instanced without reflection at MongoClientSettings

@Immutable
public final class MongoClientSettings {
    private static final CodecRegistry DEFAULT_CODEC_REGISTRY =
            fromProviders(asList(new ValueCodecProvider(),
                    new BsonValueCodecProvider(),
                    new DBRefCodecProvider(),
                    new DBObjectCodecProvider(),
                    new DocumentCodecProvider(new DocumentToDBRefTransformer()),
                    new IterableCodecProvider(new DocumentToDBRefTransformer()),
                    new MapCodecProvider(new DocumentToDBRefTransformer()),
                    new GeoJsonCodecProvider(),
                    new GridFSFileCodecProvider(),
                    new Jsr310CodecProvider(),
                    new JsonObjectCodecProvider(),
                    new BsonCodecProvider(),
                    new EnumCodecProvider(),
                    new Jep395RecordCodecProvider()));

I'm reporting this issue because I:

  • couldn't find it already created
  • got confused with the documentation
  • for a breaking change I was expecting a major version bump.

 

Regards,

  Juan.



 Comments   
Comment by Githook User [ 19/May/22 ]

Author:

{'name': 'Ross Lawley', 'email': 'ross.lawley@gmail.com', 'username': 'rozza'}

Message: RecordCodecProvider < JDK 17 canary test

The RecordCodecProvider uses JDK 17 LTS to compile.
Users maybe using older (non LTS) JDK's where records are supported.

JAVA-4605
Branch: 4.6.x
https://github.com/mongodb/mongo-java-driver/commit/c92176aa56a7319b60375d4e61e5b1be1439eaaf

Comment by Githook User [ 19/May/22 ]

Author:

{'name': 'Ross Lawley', 'email': 'ross.lawley@gmail.com', 'username': 'rozza'}

Message: RecordCodecProvider < JDK 17 canary test

The RecordCodecProvider uses JDK 17 LTS to compile.
Users maybe using older (non LTS) JDK's where records are supported.

JAVA-4605
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/1637d008e0e3eb96dbac192b0960483c9879a63d

Comment by Ross Lawley [ 19/May/22 ]

Thank juan@flowics.com,

I've been able to reproduce the issue: "It seems very possible that the Record Canary test could pass pre Java 17 but as the RecordCodecProvider is compiled using Java 17 it would lead to such an error."

I have a fix in code review.

Ross

Comment by Juan F. Codagnone [ 19/May/22 ]

I can confirm that we were using java16 (i'm reporting this on behalf a coworker that had the issue). I'll try to get the exact environment.

 

Thanks,

  Juan.

Comment by Ross Lawley [ 19/May/22 ]

I couldnt replicate the issue using Java 8 / 11 / 14 against this sample project: https://github.com/rozza/mongo-java-quickstart/tree/4.6

A full stacktrace may be helpful and more information regarding the JDK version and environment.

The Jep395RecordCodecProvider has the following canary test:

    static {
        CodecProvider possibleCodecProvider;
        try {
            Class.forName("java.lang.Record"); // JEP-395 support canary test.
            possibleCodecProvider = new RecordCodecProvider();
        } catch (ClassNotFoundException e) {
            // No JEP-395 support
            possibleCodecProvider = null;
        }
        RECORD_CODEC_PROVIDER = possibleCodecProvider;
    }

And I think joerg.heinicke@accenture.com comment points to the real issue - juan@flowics.com were you using Java 16 also? Looking at this post new features in JDK 16:

JEP 395: Records

Another preview feature introduced in JDK 14 and now finalized in JDK 16. For me, this is a beneficial addition to the Java language, as we finally have a simple way to deal with tuples.

The only change to Records from the JDK 15 implementation is to relax the longstanding restriction whereby an inner class cannot declare a member that is explicitly or implicitly static. This is very useful for simplifying certain stream operations. Often it is desirable to have a stream pass more than one object for each element. Now, a local record can be defined reducing the type pollution that would otherwise result.

It seems very possible that the Record Canary test could pass pre Java 17 but as the RecordCodecProvider is compiled using Java 17 it would lead to such an error.

Ross

Comment by Jörg Heinicke [ 18/May/22 ]

A colleague of mine had the same issue with Java 16 within IntelliJ on Mac OS x86_64. He took the easy way out though to switch to Java 17.

Comment by Jeffrey Yemin [ 17/May/22 ]

juan@flowics.com any luck with a reproducer? Just FYI, no one else has reported any issues so far, and Java 17 is not widely deployed yet.

Comment by Juan F. Codagnone [ 11/May/22 ]

Thanks Jeff, I'll try to share by the weekend an minimal enviroment.

Comment by Jeffrey Yemin [ 06/May/22 ]

Hi juan@flowics.com

We are aware that bson-record-codec requires Java 17 and that mongodb-driver-core depends on it. But we didn't anticipate any problems because of this canary test for Java 17. Jep395RecordCodecProvider itself is in mongodb-driver-core and does not require Java 17.

We also regularly test this code path using both Java 17 and Java 8.

Can you tell us a little more about your environment and perhaps provide a reproducer that demonstrates the problem? I would especially like to know what JDK you are using and how you are deploying and starting this application, and when in the lifecycle you are seeing the exception.

Generated at Thu Feb 08 09:02:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.