glebiuskv glebiuskv - 4 years ago 91
Java Question

Why does my code work?

I have code, generated under JDK8

@XmlType(name = "Client", namespace = "", propOrder = {
@Generated(value = "", date = "2016-12-07T07:34:51+04:00", comments = "JAXB RI v2.2.4-2")
public class Client {

@XmlElementRef(name = "BirthDate", namespace = "", type = JAXBElement.class, required = false)
@Generated(value = "", date = "2016-12-07T07:34:51+04:00", comments = "JAXB RI v2.2.4-2")

This code is used in an application that compiled under JDK8 with maven`s builder target set to 1.6 and run under JDK6. (Don't ask me why :( )

I am interested in how it works? The property
doesn't have the property
in JDK6 and it can't be built under it.

PS. I don't ask, why i can compile code. I'm interested why i can run it. Is it because of annotation specific, because my code don't know about property
and don't try to use it, or because of something else?

Answer Source

This is a tentative answer, that I do not claim is totally accurate, but seems a reasonnable take on this issue.

It is stated in the JLS, in the binary compatibility (emphasis mine):

13.5.7. Evolution of Annotation Types

Annotation types behave exactly like any other interface. Adding or removing an element from an annotation type is analogous to adding or removing a method. There are important considerations governing other changes to annotation types, but these have no effect on the linkage of binaries by the Java Virtual Machine. Rather, such changes affect the behavior of reflective APIs that manipulate annotations. The documentation of these APIs specifies their behavior when various changes are made to the underlying annotation types.

Adding or removing annotations has no effect on the correct linkage of the binary representations of programs in the Java programming language.

If we refer to what is said of interfaces :

13.5.3. Interface Members

Adding a method to an interface does not break compatibility with pre-existing binaries.

My understanding is that the requiered "element" of the @XmlElementRef is represented internally as an interface's method.

So you can reason about its compatibility with previous JDKs just as you would of any other interface. If you use a given method of a given interface, you need it in the interface declaration for your code to compile. This is why your code does not compile on JAXB versions priori to 2.2 (See this : JDK6 ships with JAXB 2.1.10).

However, if you have code that is already compiled (a "pre-built binary"), as long as nothing ever needs to access the said method (directly, through reflection), then it's fine for the runtime for this method not to exist.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download