-
Notifications
You must be signed in to change notification settings - Fork 96
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
Fix/payara4003 Inaccessible constructor with @ConstructorProperties #280
Conversation
…oved to ComponentMatcher. Signed-off-by: Roman Grigoriadi <[email protected]>
Added required module for ConstructorProperties-Annotation Signed-off-by: Johannes <[email protected]>
Added required module for ConstructorProperties-Annotation Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
Merge changes from original repository Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]> # Conflicts: # src/main/java/module-info.java # src/main/java/org/eclipse/yasson/internal/ConstructorPropertiesAnnotationIntrospector.java # src/main/java/org/eclipse/yasson/internal/properties/MessageKeys.java # src/main/resources/yasson-messages.properties
Signed-off-by: Johannes <[email protected]>
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.
Thanks for the PR @JohT! Just some minor review comments and then it should be good to merge.
@@ -88,6 +88,7 @@ | |||
MISSING_VALUE_PROPERTY_IN_ANNOTATION("missingValuePropertyInAnnotation"), | |||
NUMBER_INCOMPATIBLE_VALUE_TYPE_ARRAY("numberIncompatibleValueTypeArray"), | |||
NUMBER_INCOMPATIBLE_VALUE_TYPE_OBJECT("numberIncompatibleValueTypeObject"), | |||
INACCESSIBLE_CONSTRUCTOR_PROPERTIES_CREATOR("inaccessibleConstructorPropertiesCreator"), |
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.
it's not necessary to use translated message keys for debug level messages -- only INFO and above need those
@@ -31,7 +31,7 @@ | |||
return AccessController.doPrivileged((PrivilegedAction<Constructor<?>[]>) clazz::getDeclaredConstructors); | |||
} | |||
|
|||
public static class ObjectWithoutAnnotatedConstructor implements ProvidesParameterRepresentation { |
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.
I didn't name these test objects originally, but I do find the original class names to be more clear. Can we please revert the names back?
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.
I reverted them back. I named them originally and thought, they may get to long. But it is much cleaner for this branch to let it as it was.
@@ -43,6 +44,11 @@ public JsonbCreator getCreator(Constructor<?>[] constructors) { | |||
if (!(properties instanceof String[])) { | |||
continue; | |||
} | |||
if (!Modifier.isPublic(constructor.getModifiers())) { | |||
String declaringClass = constructor.getDeclaringClass().getName(); | |||
LOG.finest(Messages.getMessage(MessageKeys.INACCESSIBLE_CONSTRUCTOR_PROPERTIES_CREATOR, declaringClass, Arrays.toString((String[]) properties))); |
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.
Had a second thought on this one -- since this situation represents a static error in the code I think we should blow up with the message you've written. I see no reason to tolerate an extra annotation which will only ever be ignored by JSON-B
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.
If "we should blow up" means that we should throw an exception, then this would not solve payara/Payara#4003.
I would agree with you, when it comes to value objects, that only have this one annotated but inaccessible constructor, and no other way to construct them. This also meets the spec.
BUT :-) If there is no explicitly annotated creator, then the "normal" no-arg constructor is used to create an instance (see ObjectDeserializer.getInstance()
). This should work, regardless of any additional constructor, that is annotated with @ConstructorProperties.
Value Objects with:
- public no-arg constructor
- getter/setter or field access
- one additional, non-public constructor annotated with @ConstructorProperties
will fail to get deserialized, only because of the @ConstructorProperties-support, that came with 1.0.4. (ok, that's on me :-))
One way to solve this is to log an inaccessible @ConstructorProperties annotated constructor and ignore it. There may be a no-arg constructor later and everything is fine. There may be no way to create an instance and the deserialization would fail a bit later than it should (not that nice indeed).
The other way would be to throw an exception, but only in the case, when there is no useable other way to create an instance. This would meet the "fail fast" principle, but will lead to do the "normal" detection earlier during getCreator() additional to ObjectDeserializer.getInstance()
. This could get a bit complicated and eventually messy.
One interesting thing last but not least:
I added
"testNoArgConstructorShouldBePreferredOverUnusableJsonbAnnotatedProtectedConstructor" to "AnnotationIntrospectorTest". This test case is currently ignored, since it does not work as i'd expect. It shows, that the problem also applies to @JsonbCreator-annotated, inaccessible constructors with an additional valid no-arg constructor. The specification does not forbid the current behavior, as far as i've seen.
Both of these special cases shouldn't come up that often. But since there are generators and tools like lombok, value-objects may not always end up as they would in a hand written way.
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.
I suppose we can just log a message and move on as you suggest, but since this is a FINEST log level, lets not use a translated message from the yasson-messages resource file
Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
Is there anything I can do to help solving this? |
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.
hi @JohT, the only remaining review comment is to remove the translated message from yasson-message.properties and MessageKeys.java.
Also, if you could open up a separate issue to track the ignored test that would be great.
Once you do these we can go ahead and merge
@@ -43,6 +44,11 @@ public JsonbCreator getCreator(Constructor<?>[] constructors) { | |||
if (!(properties instanceof String[])) { | |||
continue; | |||
} | |||
if (!Modifier.isPublic(constructor.getModifiers())) { | |||
String declaringClass = constructor.getDeclaringClass().getName(); | |||
LOG.finest(Messages.getMessage(MessageKeys.INACCESSIBLE_CONSTRUCTOR_PROPERTIES_CREATOR, declaringClass, Arrays.toString((String[]) properties))); |
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.
I suppose we can just log a message and move on as you suggest, but since this is a FINEST log level, lets not use a translated message from the yasson-messages resource file
assertCreatedInstanceContainsAllParameters(ObjectWithJsonbCreatorAnnotatedProtectedConstructor.example(), creator); | ||
} | ||
|
||
// TODO Under discussion. Shouldn't this test work? |
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.
so currently this test fails with an IllegalAccessException? If so, please open up another issue and link to the URL in the comment here so we know why the test is ignored
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.
done.
i opened #326.
FYI @JohT I'm aiming to cut a 1.0.5 release of Yasson by the end of this week. If you can get the remaining review comments addressed by then we can include this PR in the 1.0.5 release |
Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
Signed-off-by: Johannes <[email protected]>
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.
looks good now. Thanks @JohT!
Fixes payara/Payara#4003.
Inaccessible constructors annotated with @ConstructorProperties should be logged (finest) and ignored.
They shouldn't override a no-arg constructor (+setter).
They shouldn't be detected as JsonbCreator anyway, since they would lead to an IllegalAccessException later during deserialization.
@ConstructorProperties support had been introduced with
#224.