-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Use synthetic functions of kotlin jvm inline class #4066
Conversation
That code has been in jackson for years. Many users have used it knowingly or unknowingly. We can't just revert it because 1 user doesn't like it. No use cases have been provided. No meaningful description has been provided. |
@pjfanning Below is the use case. Before discussing the detailed design, I created a PoC. |
Since it's a Kotlin-related problem, I wonder if it's correct to support it in a Kotlin module...
But what you said worries me too. By the way, can you reproduce the original issue? Deleting it now doesn't seem to be a problem. Can you help me reproduce the problem? |
It would be better to get consensus among the jackson-module-kotlin maintainers (eg @k163377) before looking for a jackson-databind change. It seems like this 1005 change is affecting FasterXML/jackson-module-kotlin#689 too. |
First, you can get a callable constructor without making this change. This approach has the problem that annotations given to the constructor do not work, but As long as there is a workaround, it does not seem so reasonable to change the treatment of composite constructors. However, I too would like to target composite constructors for processing. For example, what about adding a process to If this is also required in modules or libraries other than |
Hi As my PR was mentioned I will allow myself highlight problem which I have as well, assume I have class like this:
And I want to run code like this (it mimics Jackson ctor lookup):
And this will work. However, when you add an inline class to POJO it isn't gonna work:
Result is:
In case of Jackson we get a more verbose message about missing creators. Sadly, there is no way to configure that behavior, there is no class equivalent like |
Ok, I am worried too, although all unit tests do pass. But then again we don't have tests for auto-generated classes frameworks produce etc. I do think that improved handling should be added (but not via
So I won't be merging this before going on vacation, but it may be left open. |
One more thing: allowing per-class inclusion of synthetic methods would be something I'd consider, but the question is how to access this without needing to sub-class is or have global configuration. The key, at any rate, would be to limit scope of changed visibility to Kotlin (-generated) classes; allow Kotlin module indicate changed rules. |
@cowtowncoder I doubt whether this affects Scala module. |
How about this approach? #4067 |
I will also check #4066 (comment) |
You mean you want to be able to set the constructor extraction strategy using Module interface (SimpleModule / KotlinModule)?
If so, this is also possible and is a satisfactory direction. |
I don't think I'm reading your argument well, but does not using
Could you please check the At the very least, the approach you suggested is not sufficient, since the instantiation of the
Yes, it should be customizable from |
Yes, my mistake - Jackson uses declared constructors. I had too many attempts and my memory starts to plays tricks on me. But I'm pretty sure my current impl still has problem with missing creator, but will take a second look on my PR and will try to use this method. |
887e79c
to
a39e938
Compare
@k163377 Sorry, I didn't understand. |
The |
Ok, this looks doable -- but I'll need to think about it a bit; I hope to be able to give better feedback (or approve) soon but have a big backlog to go through after vacation. |
+1 on what @k163377 suggests, adding "extensible point on for modules that can override property discovery behavior". But few things to consider...
|
@@ -406,6 +411,6 @@ private final AnnotationMap collectAnnotations(AnnotatedElement main, AnnotatedE | |||
|
|||
// for [databind#1005]: do not use or expose synthetic constructors | |||
private static boolean isIncludableConstructor(Constructor<?> c) { |
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.
/cc
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 don't think current AnnotatedXxxCollector
s are optimal extension points, so suggested changes here are probably best we can do on short term. Before bigger rewrite,
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 suggested changes here are probably best we can do on short term. Before bigger rewrite,
Agreed 👍🏻
Ok, I'd be happy to merge this, if we can change this to non-draft PR? |
Personally, I am against merging this PR. It contains at least some undesirable content from a |
public static boolean isJvmInlineClassSyntheticBoxingFunction(Method method) { | ||
return Modifier.isStatic(method.getModifiers()) | ||
&& method.isSynthetic() | ||
&& method.getName().equals("box-impl"); | ||
} |
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.
As commented here, using only box-impl
to deserialize value class
may cause unexpected bugs.
#4066 (comment)
Therefore, this change should be removed.
public static boolean isJvmInlineClassSyntheticConstructor(Constructor<?> ctor) { | ||
Class<?>[] params = ctor.getParameterTypes(); | ||
if (params.length == 0) { | ||
return false; | ||
} | ||
|
||
Class<?> lastParam = params[params.length - 1]; | ||
return ctor.isSynthetic() && lastParam.getName().equals("kotlin.jvm.internal.DefaultConstructorMarker"); | ||
} |
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 code also covers constructors that do not actually contain value class
as an argument.
The following is a class definition in Kotlin
and its constructors taken from the decompiled result.
You can see that the value class
is not used, but the argument of the synthetic constructor ends with DefaultConstructorMarker
.
data class Data(val v: Int = 0)
// decompiled
public Data(int v) {
this.v = v;
}
// $FF: synthetic method
public Data(int var1, int var2, DefaultConstructorMarker var3) {
if ((var2 & 1) != 0) {
var1 = 0;
}
this(var1);
}
I can't think of any other way to write it myself, but I think it should at least be supplemented with a comment.
I thought about it again, but it seems that simply including the synthetic constructor in the processing target does not solve the problem, since the deserialization of the |
@k163377 I trust your judgment here -- I was under (wrong) impression that this alone would help solve the issue by not pruning certain synthetic constructors/factory methods. But if this alone won't help, yeah, no point in doing that. That said, I am perfectly willing to add a little bit of code (like here) where necessary to support extensions such as Kotlin or Scala module, and have appropriate scope not to change behavior of types on "other" platforms. Ideally we would have something workable here -- but I need help to known when/if this is the case. |
Looks like this PR isn't going anywhere and is out-of-date. Will close. |
WRT out-dated, stale issues, there is automated labeler as Github workflow for stale-ness we might be interested in? |
@JooHyukKim thank you for suggestion! My immediate reaction is that I am -1 for auto-close-issues Bots. Projects that use them seem to have very aggressive garbage collection, leading to (IMHO) hostile experience for submitters. So while I have sympathy for maintainers, personally I much prefer actual human beings closing issues over automated processes. But this is only for Bots that actually close issues -- I would not be against auto-labeller? |
Np, @cowtowncoder 👍🏼 I agree, closing would be too agressive. And yes it will be just labeler. Okay, will get into it. |
Sounds good -- and we could/should probably only enable it (if we do) for some of highest-traffic repos. |
Background
To support kotlin value class,
Synthetic Kotlin constructors should be available
revert: #1005