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

Fix/payara4003 Inaccessible constructor with @ConstructorProperties #280

Merged
merged 17 commits into from
Sep 5, 2019

Conversation

JohT
Copy link
Contributor

@JohT JohT commented Jul 3, 2019

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.

JohT and others added 12 commits February 11, 2019 20:19
…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]>
Merge changes from original repository

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]>
@JohT JohT force-pushed the fix/payara4003 branch from bd2f279 to 9d089ce Compare July 3, 2019 18:36
Copy link
Member

@aguibert aguibert left a 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"),
Copy link
Member

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 {
Copy link
Member

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?

Copy link
Contributor Author

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)));
Copy link
Member

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

Copy link
Contributor Author

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.

Copy link
Member

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

@JohT
Copy link
Contributor Author

JohT commented Sep 2, 2019

Is there anything I can do to help solving this?

Copy link
Member

@aguibert aguibert left a 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)));
Copy link
Member

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?
Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.
i opened #326.

@aguibert
Copy link
Member

aguibert commented Sep 3, 2019

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

Copy link
Member

@aguibert aguibert left a 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!

@aguibert aguibert merged commit 09d7a24 into eclipse-ee4j:master Sep 5, 2019
@aguibert aguibert added the bug Something isn't working right label Sep 6, 2019
@aguibert aguibert added this to the 1.0.5 milestone Sep 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working right
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JSONB does not deserialize with private contruction annnotated with @ConstructorProperties /CUSTCOM-40
2 participants