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