-
Notifications
You must be signed in to change notification settings - Fork 832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Records in JDK 14 #766
Conversation
@FrauBoes: This is great! Thanks again for taking the time to implement this.
That's perfectly fine with me. This is just an implementation detail and can be changed later on if necessary.
FieldSerializer orders by name because the order of fields returned by
👍
Yes, we should add a We can probably move to a JDK11 target and compile with JDK14+ in Kryo 6. This will make the test setup much simpler and we can get rid of all the reflection currently required for
This looks good to me. It is basically the same approach we currently use to run JDK11 tests while still targeting JDK8.
That can be fixed. We just need to use a different constructor in
instead of:
I have some other minor comments that I will add as a PR review. |
src/com/esotericsoftware/kryo/serializers/RecordSerializer.java
Outdated
Show resolved
Hide resolved
@magro: Could you take a look at this as well? The main decision we have to make is if we want to include support for records in Kryo 5 or not. If we set the baseline for Kryo 6 to JDK11 and compile using JDK14+, the implementation of the serializer would be significantly simpler. |
Jackson chose a slightly different (and simpler) approach for separating tests for different JDK versions: FasterXML/jackson-databind#2714 They use a different root folder for tests that depend on a certain JDK version:
I think we should adopt the same approach. |
@theigl Yes,
|
One advantage of ordering record components by name is that it facilitates duck typing of different record type versions. It's not required but provides more flexibility. |
@ChrisHegarty: Thanks for clarifying this!
@FrauBoes: Either way is fine for me as long as we don't need to break serialization compatibility later on. What I don't quite understand is this: How would you invoke the constructor with the right order of arguments if they are sorted by name? |
@@ -124,7 +125,7 @@ public static ByteBuffer newDirectBuffer (long address, int size) { | |||
if (directByteBufferConstructor == null) | |||
throw new UnsupportedOperationException("No direct ByteBuffer constructor is available."); | |||
try { | |||
return directByteBufferConstructor.newInstance(address, size, null); | |||
return directByteBufferConstructor.newInstance(address, size); | |||
} catch (Exception ex) { | |||
throw new KryoException("Error creating a ByteBuffer at address: " + address, ex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is unrelated to records, but is clearly required to successfully run on JDK 14+, since the non-Public constructors of DirectByteBuffer has been refactored / changed.
@theigl Thanks for your comments so far.
That's indeed not that straight-forward. I have a version working that uses an in-memory compiler and a custom classloader to instantiate a record at runtime. It's a lot of utility code for a single test case so I would suggest to put a stripped down copy of
This is definitely an option. It's based on the fact that in this location maven ignores the
The idea would be to order by name before serialization and expect the same order at deserialization. The order can be stored as part of the |
Let's go for the simplest approach! I think it should be possible to put only the TestData into the jdk14 folder and add it to the test datas in SerializationCompatTest via
Your current solution looks good to me! Everything is in one place and we do not need any another plugin.
That sounds reasonable. Let's go for the ordered implementation if the code for ordering does not greatly increase the complexity of the serializer. |
Added |
@theigl I tried to build with the IntelliJ Maven integration and it works fine with JDK14. What I do:
If the profile is not selected, compilation with JDK14 fails. Could that be the issue? I'm still happy to make the change, but want to understand the issue. |
@FrauBoes: The problem is not the IntelliJ Maven Integration. That can be made to work. I was referring to opening any test in IntelliJ and simply running it. IntelliJ then tries to compile all classes and fails: This is because IntelliJ infers the language level from Maven when importing the project. In the Jackson setup, they override the default language level for the JDK14 profile and force IntelliJ to use JDK14. This, and upgrading the Maven shade plugin allowed me to run individual tests in IntelliJ as described above. If we now switch the project SDK to JDK11 and try to run a test from within IntelliJ, it fails. This is because IntelliJ does not understand Maven excludes and tries to compile To summarize: The goal is that any user on JDK11 - 15 should be able to checkout the project, build it with Maven, and run individual unit tests directly in IntelliJ. Our current approach fails in the last requirement. |
@theigl Gotcha, now I understand the requirements. I'll look into making the change. Thanks! |
int[] versions = new int[] {parseInt(strVersions[0]), parseInt(strVersions[1])}; | ||
JAVA_VERSION = versions[0] > 1 ? versions[0] : versions[1]; | ||
if (strVersions.length == 1) { | ||
JAVA_VERSION = parseInt(strVersions[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated change to better support version strings
Made the change we discussed. I'm able to build with Maven and run individual tests in IntelliJ with JDK 11, 14 and 15. The only caveat is that jdk14 tests are not compiled automatically when the project SDK is set to JDK14+, one has to build with Maven first. I'm not sure if that's related to my specific IDE build configurations. |
@FrauBoes: This works great! I had the same issue with the jdk14 tests but I don't think this is that much of a problem. The only thing that bothers me now is that we use a different approach for jdk11. I think we should consolidate this and use a custom Please also remove the |
If you can, please import code format and import order from the |
Agreed, I moved the jdk11 tests to the root and added a |
@FrauBoes: Thanks a lot! I think this PR turned out great! 👍 There is only one last thing: The copyright headers. Nathan and I don't feel comfortable with this. We would greatly prefer it if you add yourself or Oracle as |
Thanks for reviewing the contribution, @theigl, it definitely made for a better result. With regards to the copyright header, let me look into this and get back to you. |
@FrauBoes: Did you get any feedback on the copyright headers? Kryo 5.0.0 has been released and is quite stable, so we could apply this PR now. |
@theigl We are still on it. I'll get back to you as soon as I know more. |
Hi @theigl, sorry for the delay. We’re still working through getting the approvals necessary to contribute. Would it be possible for you to modify the last sentence in the CONTRIBUTING.md from
to something like the following, which we feel will make the connection clearer between the contribution, license, and copyright:
? |
@FrauBoes: Thanks for the update! I'll ask @NathanSweet and get back to you. |
@FrauBoes: The suggested change would be OK for us. |
Hi @theigl, we got the green light and can move ahead with the contribution \o/. I've added |
@FrauBoes: Thanks a lot for the updated PR! I just released the current master as Kryo 5.0.4 and will review (and most likely merge) your PR in the next couple of days. |
@theigl That's great news. Very happy to see Kryo support records! Thanks again for your input and engagement on the PR, as said before it made for a better result. If anything else comes up along the way, let me know. |
Merged! 🎉 I will create a release (or RC) with your changes in the next couple of days. |
@FrauBoes: I realized today that the I think we should switch to core reflection for the time being. Is this something you could help with? Sorry that I didn't think about this before merging your PR! |
@theigl I can help with that. I'll create a new PR in the next few days. |
Here is the initial version of a record serializer. A few things to note:
FieldSerialiser
orders by name, this could be done here as well.RecordSerializerTest
, this can be cleaned up before integration.RecordSerializerTest
was added to the default serializers. Do we needs to add a test case toSerializerCompatTest.TestData
?--enable-preview
. I am not very familiar with Maven and ended up with this solution after asking a few questions on their mailing list. There might well be a better way of handling test compilation and test runs.UnsafeByteBufferInputOutputTest
[INFO] Running com.esotericsoftware.kryo.io.UnsafeByteBufferInputOutputTest Streams with preallocated direct memory are not supported on this JVM java.lang.UnsupportedOperationException: No direct ByteBuffer constructor is available. at com.esotericsoftware.kryo.unsafe.UnsafeUtil.newDirectBuffer(UnsafeUtil.java:125) at com.esotericsoftware.kryo.io.UnsafeByteBufferInputOutputTest.testByteBufferOutputWithPreallocatedMemory(UnsafeByteBufferInputOutputTest.java:43)
I'm sure there are plenty of things that can be improved. Any suggestions welcome!