RFR 7199353: Allow ConstructorProperties annotation from any package

Peter Levart peter.levart at gmail.com
Fri Oct 9 11:42:12 UTC 2015


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-



More information about the jigsaw-dev mailing list