Skip to content
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

Some review comments on records support #1

Merged

Conversation

ChrisHegarty
Copy link

  1. Update pom support to be Java 14+
  2. Store Method references to avoid subsequent lookup
  3. All test records should be public

1) Update pom support to be Java 14+
2) Store Method references to avoid subsequent lookup
3) All test records should be public
<source>14</source>
<target>14</target>
<!-- Enable Java 14+ for all sources so that Intellij picks the right language level -->
<release>${java.vm.specification.version}</release>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using this property, in my setup Intellij does not pickup the correct version for language level support
Would putting 14 be acceptable?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works fine for me with maven, but i have not tried with Intellij.

The reason I proposed this change is so that the release version will work with Java versions greater than 14, say e.g. 15 and beyond. java.vm.specification.version is a standard Java SE system property, and Maven exposes all properties from java.lang.System, so it is surprising that it is not working in Intellij. It's ok to drop this, for now. We can figure out if/how we want the version to roll later, if needed.

@@ -52,7 +52,7 @@ public void testDeserializeSimpleRecord_DisableAnnotationIntrospector() throws I
assertEquals(new SimpleRecord(123, "Bob"), value);
}

record RecordOfRecord(SimpleRecord record) {
public record RecordOfRecord(SimpleRecord record) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All test records should be public

Why? (just for me to understand :))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Java 14 a record's canonical constructor is always public ( it has the public modifier ).
In Java 15 (and beyond) a record's canonical constructor inherits the access control modifier from that of the record declaration.

So without the change to make the record declarations public, then in Java 15 the canonical constructor is package-private, and by default Jackson cannot locale it. Now, this could be an issue or change with the default deserialisation policy in the version of the latest branch that I tested against.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to try access of non-public Records too, for parity with POJOs. Although I don't know if it is possible to configure access for tests in a way that this is actually allowed (I assume module-info declarations are needed?).

Copy link
Author

@ChrisHegarty ChrisHegarty Jul 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding tests to check for non-public Records would be good ( we have such in the JDK serialization unit tests ).

When running the existing RecordTest in my local environment with a JDK 15 early-access build I did see failures - since the record's canonical constructor was not public (it was package-private inherited from the record declaration). These failures may be because I was using the tip of jackson-databind where the default visibility of creator differs? Or maybe because of not explicitly setting the visibility checker in the test? I'm not sure. Either way, it should be possible to write tests where the record (and it's canonical constructor) are not accessible to Jackson ( package-private ), and ensure that whatever deserialization/visibility configuration work as expected.

<activation>
<jdk>14</jdk>
<jdk>[14,</jdk>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

private static final String RECORD_COMPONENT_CLASS_NAME = "java.lang.reflect.RecordComponent";
private static final String RECORD_COMPONENT_GET_NAME = "getName";
private static final String RECORD_COMPONENT_GET_TYPE = "getType";
static {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 and it has been suggested by @cowtowncoder as well

@ChrisHegarty
Copy link
Author

I have changes in the works to replace the user of core reflection, in RecordUtils, with Method Handles. I'm still verifying the changes, but in general the use of method handles will be more performant than that of core reflection. Again, this should not be a blocker, and can be considered separately, on its own merit.

@youribonnaffe youribonnaffe merged commit 20684d7 into youribonnaffe:java-14-records Jul 7, 2020
@cowtowncoder
Copy link

Use of MethodHandle may make sense and can be done (added in JDK7, right?), assuming they are usable on Android too.
Then again this particular use should never be on critical path as it's just on introspection and (de)serializers getting cached should mean it is one-off startup cost typically.
Not that I am against any and all performance improvements, esp. in cases where there may be other benefits (more readable code?).

But for actual property access MethodHandles might have performance benefits too; I think there were some mixed opinions whether there are or not but that should be easy enough to test as changes should be relatively isolated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants