Hi,

I don't think it has been mentioned before, but is @ConstructorProperties still necessary in JDK8+ ? Couldn't the j.l.r.Constructor#getParameters() be used instead?

How is one supposed to compile an MXBean that would work in JDK8 and at the same time in JDK9+ without java.desktop in the module graph?

What if the construction of MXBean int JDK9 worked like this (added point #5):

For any given J, the following rules are consulted to determine how to reconstruct instances of J from CompositeData. The first applicable rule in the list is the one that will be used.

1.    If J has a method
    public static J from(CompositeData cd)
    then that method is called to reconstruct an instance of J.

2. Otherwise, if J has at least one public constructor with a ConstructorProperties annotation, then one of those constructors (not necessarily always the same one) will be called to reconstruct an instance of J. Every such annotation must list as many strings as the constructor has parameters; each string must name a property corresponding to a getter of J; and the type of this getter must be the same as the corresponding constructor parameter. It is not an error for there to be getters that are not mentioned in the ConstructorProperties annotation (these may correspond to information that is not needed to reconstruct the object).

An instance of J is reconstructed by calling a constructor with the appropriate reconstructed items from the CompositeData. The constructor to be called will be determined at runtime based on the items actually present in the CompositeData, given that this CompositeData might come from an earlier version of J where not all the items were present. A constructor is applicable if all the properties named in its ConstructorProperties annotation are present as items in the CompositeData. If no constructor is applicable, then the attempt to reconstruct J fails.

For any possible combination of properties, it must be the case that either (a) there are no applicable constructors, or (b) there is exactly one applicable constructor, or (c) one of the applicable constructors names a proper superset of the properties named by each other applicable constructor. (In other words, there should never be ambiguity over which constructor to choose.) If this condition is not true, then J is not reconstructible.

3. Otherwise, if J has a public no-arg constructor, and for every getter in J with type T and name N there is a corresponding setter with the same name and type, then an instance of J is constructed with the no-arg constructor and the setters are called with the reconstructed items from the CompositeData to restore the values. For example, if there is a method
    public List<String> getNames()
    then there must also be a method
    public void setNames(List<String> names)
    for this rule to apply.

If the CompositeData came from an earlier version of J, some items might not be present. In this case, the corresponding setters will not be called.

4. Otherwise, if J is an interface that has no methods other than getters, an instance of J is constructed using a Proxy with a CompositeDataInvocationHandler backed by the CompositeData being converted.

*5. Otherwise, if J has at least one public constructor with {@link Constructor#getParameters parameters} having {@link Parameter#getName name}s where each of them matches a property corresponding to a getter of J, then one of those constructors (not necessarily always the same one) will be called to reconstruct an instance of J. The type of each such constructor parameter must be the same as the equally named property corresponding to a getter. It is not an error for there to be getters that don't have a corresponding constructor parameter with the same name (these may correspond to information that is not needed to reconstruct the object).**
**
** An instance of J is reconstructed by calling a constructor with the appropriate reconstructed items from the CompositeData. The constructor to be called will be determined at runtime based on the items actually present in the CompositeData, given that this CompositeData might come from an earlier version of J where not all the items were present. A constructor is applicable if all it's parameters are present as equaly-named items in the CompositeData. If no constructor is applicable, then the attempt to reconstruct J fails.**
****
** For any possible combination of properties, it must be the case that either (a) there are no applicable constructors, or (b) there is exactly one applicable constructor, or (c) one of the applicable constructors names a proper superset of the parameters named by each other applicable constructor. (In other words, there should never be ambiguity over which constructor to choose.) If this condition is not true, then J is not reconstructible.*

6.    Otherwise, J is not reconstructible.


This, I think, should be back-compatible as it adds just another option at the end.

To answer my question: "How is one supposed to compile an MXBean that would work in JDK8- and at the same time in JDK9+ without java.desktop in the module graph?"

The MXBean should be compiled by JDK8, it should annotate all public > 0 arg constructors with @java.beans.ConstructorProperties and make sure those public constructor parameters have the same names as corresponding bean properties.

If there's no java.desktop in the module graph, @java.beans.ConstructorProperties are unretrievable and MXBean will use the rules from #5 above.



What do you think?


Regards, Peter

On 10/08/2015 01:49 PM, Jaroslav Bachorik wrote:
Please, review the following change

Issue : https://bugs.openjdk.java.net/browse/JDK-7199353
Webrev: http://cr.openjdk.java.net/~jbachorik/7199353/webrev.00/top
http://cr.openjdk.java.net/~jbachorik/7199353/webrev.00/jdk

Issue description:
"MXBean currently supports model-specific types annotated with
java.beans.ConstructorProperties that is tightly coupled with
the client API. A MXBean developer will likely want to avoid
using java.beans.ConstructorProperties if it ends up in the
desktop module that their code doesn't want to pull in. In
that case, the code has to write to achieve the same effort
by defining the from(CompositeData) method."

This patch adds a new annotation @javax.management.annotation.ConstructorProperties which can be used in stead of @java.beans.ConstructorProperties. This will allow the developers to use this convenience feature without introducing a bit strange dependency on java.desktop.

For the backward compatibility purposes @java.beans.ConstructorProperties annotation will still be recognized by the JMX system but a) A warning will be logged about using a deprecated way to specify @ConstructorProperties b) If there is also @javax.management.annotation.ConstructorProperties annotation present on the same constructor then only this annotation will be considered.

All the tests exercising the JMX related @ConstructorProperties functionality have been updated to use @javax.management.annotation.ConstructorProperties.

Since this change is affecting public APIs the relevant CCC request has been filed and is in processing now.


Thanks,

-JB-

Reply via email to