Initial JDK 11 RFR of JDK-8202385: Annotation to mark serial-related fields and methods
Hello, Please review the webrev (code below) to address JDK-8202385: Annotation to mark serial-related fields and methods http://cr.openjdk.java.net/~darcy/8202385.0/ The proposed java.io.Serial annotation type is intended to be used along with an augmented implementation of javac's "serial" lint check; that work will be done separately as part of JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods". Currently, javac's serial lint check looks for serialVersionUID fields to be declared in Serializable classes. However, there are various other structural properties of the declaration of serialization-related fields and methods that could be checked at compile-time. The proposed java.io.Serial annotation type (name subject to change [*]) explicitly marks fields and methods that are intended to be called as part of the Serialization machinery. This marking allows using the wrong name for a method or field to be easily caught; the serialization mechanism will generally silently ignore mis-declared serialization-related fields and methods. Since the annotation is intended for compile-time checking, the annotation type has has source retention, like the Override annotation type. Cheers, -Joe [*] Unleash the bikes from the bikeshed! On the name and package of the annotation type, since the other serialization types are in the java.io package and the checks are not proposed to be part of the language, this annotation type more appropriately lives in java.io package rather than java.lang. The name "Serial" is consistent with the "@serial" javadoc tag. Other possible names include "Serialize" and "SerialRelated". Another possibility would be to have the annotation type be a nested type in java.io.Serializable. -=-=-=-=-=-=- // GPLv2 elided. package java.io; import java.lang.annotation.*; /** * Indicates that a field or method is related to the {@linkplain * Serializable serialization mechanism}. This annotation type is * intended to allow compile-time checking of serialization-related * declarations, analogous to the checking enabled by the {@link * java.lang.Override} annotation type to validate method overriding. * * <p>Specifically, annotations of this type are intended to be * applied to serialization-related methods and fields in classes * declared to be {@code Serializable}. The five serialization-related * methods are: * * <ul> * <li>{@code private void writeObject(java.io.ObjectOutputStream stream) throws IOException} * <li>{@code private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException} * <li>{@code private void readObjectNoData() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object writeReplace() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object readResolve() throws ObjectStreamException} * </ul> * * The two serialization-related fields are: * * <ul> * <li>{@code private static final ObjectStreamField[] serialPersistentFields} * <li>{@code private static final long serialVersionUID} * </ul> * * A compiler can validate that a method or field marked with a * <code>@Serial</code> annotation is one of the defined serialization-related * methods declared in a meaningful context. * * <p>It is a semantic error to apply this annotation to other fields or methods, including: * <ul> * <li>fields or methods in a class that is not {@code Serializable} * * <li>fields or methods of the proper structural declaration, but in * a type where they are ineffectual. For example, {@code enum} types * are defined to have a {@code serialVersionUID} of {@code 0L} so a * {@code serialVersionUID} field declared in an {@code enum} type is * ignored. The five serialization-related methods identified above * are likewise ignored for an {@code enum} type. * * </ul> */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.SOURCE) public @interface Serial { }
Hi Joe, Since Externalizable extends Serializable, should it or its methods be mentioned, either in the list to be marked as @Serial or not to be. Thanks, Roger On 5/10/2018 11:55 AM, joe darcy wrote:
Hello,
Please review the webrev (code below) to address
JDK-8202385: Annotation to mark serial-related fields and methods http://cr.openjdk.java.net/~darcy/8202385.0/
The proposed java.io.Serial annotation type is intended to be used along with an augmented implementation of javac's "serial" lint check; that work will be done separately as part of JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods".
Currently, javac's serial lint check looks for serialVersionUID fields to be declared in Serializable classes. However, there are various other structural properties of the declaration of serialization-related fields and methods that could be checked at compile-time. The proposed java.io.Serial annotation type (name subject to change [*]) explicitly marks fields and methods that are intended to be called as part of the Serialization machinery. This marking allows using the wrong name for a method or field to be easily caught; the serialization mechanism will generally silently ignore mis-declared serialization-related fields and methods.
Since the annotation is intended for compile-time checking, the annotation type has has source retention, like the Override annotation type.
Cheers,
-Joe
[*] Unleash the bikes from the bikeshed! On the name and package of the annotation type, since the other serialization types are in the java.io package and the checks are not proposed to be part of the language, this annotation type more appropriately lives in java.io package rather than java.lang. The name "Serial" is consistent with the "@serial" javadoc tag. Other possible names include "Serialize" and "SerialRelated". Another possibility would be to have the annotation type be a nested type in java.io.Serializable.
-=-=-=-=-=-=-
// GPLv2 elided.
package java.io;
import java.lang.annotation.*;
/** * Indicates that a field or method is related to the {@linkplain * Serializable serialization mechanism}. This annotation type is * intended to allow compile-time checking of serialization-related * declarations, analogous to the checking enabled by the {@link * java.lang.Override} annotation type to validate method overriding. * * <p>Specifically, annotations of this type are intended to be * applied to serialization-related methods and fields in classes * declared to be {@code Serializable}. The five serialization-related * methods are: * * <ul> * <li>{@code private void writeObject(java.io.ObjectOutputStream stream) throws IOException} * <li>{@code private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException} * <li>{@code private void readObjectNoData() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object writeReplace() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object readResolve() throws ObjectStreamException} * </ul> * * The two serialization-related fields are: * * <ul> * <li>{@code private static final ObjectStreamField[] serialPersistentFields} * <li>{@code private static final long serialVersionUID} * </ul> * * A compiler can validate that a method or field marked with a * <code>@Serial</code> annotation is one of the defined serialization-related * methods declared in a meaningful context. * * <p>It is a semantic error to apply this annotation to other fields or methods, including: * <ul> * <li>fields or methods in a class that is not {@code Serializable} * * <li>fields or methods of the proper structural declaration, but in * a type where they are ineffectual. For example, {@code enum} types * are defined to have a {@code serialVersionUID} of {@code 0L} so a * {@code serialVersionUID} field declared in an {@code enum} type is * ignored. The five serialization-related methods identified above * are likewise ignored for an {@code enum} type. * * </ul> */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.SOURCE) public @interface Serial { }
Hi Roger, Right; there are a few other distinguished methods defined for externalization, but they are defined on the as methods on the Externalizable interface as far as I can tell. The existence of externalization is mentioned in the javac lint bug JDK-8202385. I'll add as sentence indicating that the checks are for "Serializable but not Externalizable" classes. Thanks, -Joe On 5/10/2018 12:37 PM, Roger Riggs wrote:
Hi Joe,
Since Externalizable extends Serializable, should it or its methods be mentioned, either in the list to be marked as @Serial or not to be.
Thanks, Roger
On 5/10/2018 11:55 AM, joe darcy wrote:
Hello,
Please review the webrev (code below) to address
JDK-8202385: Annotation to mark serial-related fields and methods http://cr.openjdk.java.net/~darcy/8202385.0/
The proposed java.io.Serial annotation type is intended to be used along with an augmented implementation of javac's "serial" lint check; that work will be done separately as part of JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods".
Currently, javac's serial lint check looks for serialVersionUID fields to be declared in Serializable classes. However, there are various other structural properties of the declaration of serialization-related fields and methods that could be checked at compile-time. The proposed java.io.Serial annotation type (name subject to change [*]) explicitly marks fields and methods that are intended to be called as part of the Serialization machinery. This marking allows using the wrong name for a method or field to be easily caught; the serialization mechanism will generally silently ignore mis-declared serialization-related fields and methods.
Since the annotation is intended for compile-time checking, the annotation type has has source retention, like the Override annotation type.
Cheers,
-Joe
[*] Unleash the bikes from the bikeshed! On the name and package of the annotation type, since the other serialization types are in the java.io package and the checks are not proposed to be part of the language, this annotation type more appropriately lives in java.io package rather than java.lang. The name "Serial" is consistent with the "@serial" javadoc tag. Other possible names include "Serialize" and "SerialRelated". Another possibility would be to have the annotation type be a nested type in java.io.Serializable.
-=-=-=-=-=-=-
// GPLv2 elided.
package java.io;
import java.lang.annotation.*;
/** * Indicates that a field or method is related to the {@linkplain * Serializable serialization mechanism}. This annotation type is * intended to allow compile-time checking of serialization-related * declarations, analogous to the checking enabled by the {@link * java.lang.Override} annotation type to validate method overriding. * * <p>Specifically, annotations of this type are intended to be * applied to serialization-related methods and fields in classes * declared to be {@code Serializable}. The five serialization-related * methods are: * * <ul> * <li>{@code private void writeObject(java.io.ObjectOutputStream stream) throws IOException} * <li>{@code private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException} * <li>{@code private void readObjectNoData() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object writeReplace() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object readResolve() throws ObjectStreamException} * </ul> * * The two serialization-related fields are: * * <ul> * <li>{@code private static final ObjectStreamField[] serialPersistentFields} * <li>{@code private static final long serialVersionUID} * </ul> * * A compiler can validate that a method or field marked with a * <code>@Serial</code> annotation is one of the defined serialization-related * methods declared in a meaningful context. * * <p>It is a semantic error to apply this annotation to other fields or methods, including: * <ul> * <li>fields or methods in a class that is not {@code Serializable} * * <li>fields or methods of the proper structural declaration, but in * a type where they are ineffectual. For example, {@code enum} types * are defined to have a {@code serialVersionUID} of {@code 0L} so a * {@code serialVersionUID} field declared in an {@code enum} type is * ignored. The five serialization-related methods identified above * are likewise ignored for an {@code enum} type. * * </ul> */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.SOURCE) public @interface Serial { }
PS After additional reading, I propose to add the follow clause to where using the annotation is not appropriate: * <li>the {@code writeObject}, {@code readObject}, and {@code * readObjectNoData} methods in a class that is {@code * Externalizable}. While the {@code Externalizable} interface extends * {@code Serializable}, those three methods are not used for * externalizable classes. How does that sound? Thanks, -Joe On 5/10/2018 1:22 PM, joe darcy wrote:
Hi Roger,
Right; there are a few other distinguished methods defined for externalization, but they are defined on the as methods on the Externalizable interface as far as I can tell. The existence of externalization is mentioned in the javac lint bug JDK-8202385.
I'll add as sentence indicating that the checks are for "Serializable but not Externalizable" classes.
Thanks,
-Joe
Hi Joe, The words are fine. The field serialPersistentFields is also not used with @Externalizable. I would guess the lint checker would flag those methods and field for warnings for Externalizable classes since they might mislead to think they were used. Roger On 5/10/2018 5:03 PM, joe darcy wrote:
PS After additional reading, I propose to add the follow clause to where using the annotation is not appropriate:
* <li>the {@code writeObject}, {@code readObject}, and {@code * readObjectNoData} methods in a class that is {@code * Externalizable}. While the {@code Externalizable} interface extends * {@code Serializable}, those three methods are not used for * externalizable classes.
How does that sound?
Thanks,
-Joe
On 5/10/2018 1:22 PM, joe darcy wrote:
Hi Roger,
Right; there are a few other distinguished methods defined for externalization, but they are defined on the as methods on the Externalizable interface as far as I can tell. The existence of externalization is mentioned in the javac lint bug JDK-8202385.
I'll add as sentence indicating that the checks are for "Serializable but not Externalizable" classes.
Thanks,
-Joe
Hi Roger, Returning to this topic, I'll add a clause in the spec for serialPersistentFields and Externalizable and corresponding code in the checker. Should there be a similar check for serialVersionUID in an Externalizable class? It wasn't clear to me from reading the specs and there are cases in the JDK of classes implementing Externalizable and having serialVersionUID fields defined. Thanks, -Joe On 5/10/2018 2:26 PM, Roger Riggs wrote:
Hi Joe,
The words are fine.
The field serialPersistentFields is also not used with @Externalizable.
I would guess the lint checker would flag those methods and field for warnings for Externalizable classes since they might mislead to think they were used.
Roger
On 5/10/2018 5:03 PM, joe darcy wrote:
PS After additional reading, I propose to add the follow clause to where using the annotation is not appropriate:
* <li>the {@code writeObject}, {@code readObject}, and {@code * readObjectNoData} methods in a class that is {@code * Externalizable}. While the {@code Externalizable} interface extends * {@code Serializable}, those three methods are not used for * externalizable classes.
How does that sound?
Thanks,
-Joe
On 5/10/2018 1:22 PM, joe darcy wrote:
Hi Roger,
Right; there are a few other distinguished methods defined for externalization, but they are defined on the as methods on the Externalizable interface as far as I can tell. The existence of externalization is mentioned in the javac lint bug JDK-8202385.
I'll add as sentence indicating that the checks are for "Serializable but not Externalizable" classes.
Thanks,
-Joe
Hi Joe, serialVersionUID is used to confirm the identity of a class so it is applicable to classes implementing Externalizable as well as Serializable. (And also serialization of a class itself). Thanks, Roger On 8/10/18 1:39 PM, joe darcy wrote:
Hi Roger,
Returning to this topic, I'll add a clause in the spec for serialPersistentFields and Externalizable and corresponding code in the checker. Should there be a similar check for serialVersionUID in an Externalizable class? It wasn't clear to me from reading the specs and there are cases in the JDK of classes implementing Externalizable and having serialVersionUID fields defined.
Thanks,
-Joe
On 5/10/2018 2:26 PM, Roger Riggs wrote:
Hi Joe,
The words are fine.
The field serialPersistentFields is also not used with @Externalizable.
I would guess the lint checker would flag those methods and field for warnings for Externalizable classes since they might mislead to think they were used.
Roger
On 5/10/2018 5:03 PM, joe darcy wrote:
PS After additional reading, I propose to add the follow clause to where using the annotation is not appropriate:
* <li>the {@code writeObject}, {@code readObject}, and {@code * readObjectNoData} methods in a class that is {@code * Externalizable}. While the {@code Externalizable} interface extends * {@code Serializable}, those three methods are not used for * externalizable classes.
How does that sound?
Thanks,
-Joe
On 5/10/2018 1:22 PM, joe darcy wrote:
Hi Roger,
Right; there are a few other distinguished methods defined for externalization, but they are defined on the as methods on the Externalizable interface as far as I can tell. The existence of externalization is mentioned in the javac lint bug JDK-8202385.
I'll add as sentence indicating that the checks are for "Serializable but not Externalizable" classes.
Thanks,
-Joe
Hi Roger, Thanks for the explanation; I'll adjust the proposed java.io.Serial spec and serialization-related check accordingly. Cheers, -Joe On 8/10/2018 11:02 AM, Roger Riggs wrote:
Hi Joe,
serialVersionUID is used to confirm the identity of a class so it is applicable to classes implementing Externalizable as well as Serializable. (And also serialization of a class itself).
Thanks, Roger
On 8/10/18 1:39 PM, joe darcy wrote:
Hi Roger,
Returning to this topic, I'll add a clause in the spec for serialPersistentFields and Externalizable and corresponding code in the checker. Should there be a similar check for serialVersionUID in an Externalizable class? It wasn't clear to me from reading the specs and there are cases in the JDK of classes implementing Externalizable and having serialVersionUID fields defined.
Thanks,
-Joe
On 5/10/2018 2:26 PM, Roger Riggs wrote:
Hi Joe,
The words are fine.
The field serialPersistentFields is also not used with @Externalizable.
I would guess the lint checker would flag those methods and field for warnings for Externalizable classes since they might mislead to think they were used.
Roger
On 5/10/2018 5:03 PM, joe darcy wrote:
PS After additional reading, I propose to add the follow clause to where using the annotation is not appropriate:
* <li>the {@code writeObject}, {@code readObject}, and {@code * readObjectNoData} methods in a class that is {@code * Externalizable}. While the {@code Externalizable} interface extends * {@code Serializable}, those three methods are not used for * externalizable classes.
How does that sound?
Thanks,
-Joe
On 5/10/2018 1:22 PM, joe darcy wrote:
Hi Roger,
Right; there are a few other distinguished methods defined for externalization, but they are defined on the as methods on the Externalizable interface as far as I can tell. The existence of externalization is mentioned in the javac lint bug JDK-8202385.
I'll add as sentence indicating that the checks are for "Serializable but not Externalizable" classes.
Thanks,
-Joe
Would it be allowed to enable the serial lint without using the @Serial annotation? On Thu, May 10, 2018 at 10:55 AM, joe darcy <joe.darcy@oracle.com> wrote:
Hello,
Please review the webrev (code below) to address
JDK-8202385: Annotation to mark serial-related fields and methods http://cr.openjdk.java.net/~darcy/8202385.0/
The proposed java.io.Serial annotation type is intended to be used along with an augmented implementation of javac's "serial" lint check; that work will be done separately as part of JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods".
Currently, javac's serial lint check looks for serialVersionUID fields to be declared in Serializable classes. However, there are various other structural properties of the declaration of serialization-related fields and methods that could be checked at compile-time. The proposed java.io.Serial annotation type (name subject to change [*]) explicitly marks fields and methods that are intended to be called as part of the Serialization machinery. This marking allows using the wrong name for a method or field to be easily caught; the serialization mechanism will generally silently ignore mis-declared serialization-related fields and methods.
Since the annotation is intended for compile-time checking, the annotation type has has source retention, like the Override annotation type.
Cheers,
-Joe
[*] Unleash the bikes from the bikeshed! On the name and package of the annotation type, since the other serialization types are in the java.io package and the checks are not proposed to be part of the language, this annotation type more appropriately lives in java.io package rather than java.lang. The name "Serial" is consistent with the "@serial" javadoc tag. Other possible names include "Serialize" and "SerialRelated". Another possibility would be to have the annotation type be a nested type in java.io.Serializable.
-=-=-=-=-=-=-
// GPLv2 elided.
package java.io;
import java.lang.annotation.*;
/** * Indicates that a field or method is related to the {@linkplain * Serializable serialization mechanism}. This annotation type is * intended to allow compile-time checking of serialization-related * declarations, analogous to the checking enabled by the {@link * java.lang.Override} annotation type to validate method overriding. * * <p>Specifically, annotations of this type are intended to be * applied to serialization-related methods and fields in classes * declared to be {@code Serializable}. The five serialization-related * methods are: * * <ul> * <li>{@code private void writeObject(java.io.ObjectOutputStream stream) throws IOException} * <li>{@code private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException} * <li>{@code private void readObjectNoData() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object writeReplace() throws ObjectStreamException} * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object readResolve() throws ObjectStreamException} * </ul> * * The two serialization-related fields are: * * <ul> * <li>{@code private static final ObjectStreamField[] serialPersistentFields} * <li>{@code private static final long serialVersionUID} * </ul> * * A compiler can validate that a method or field marked with a * <code>@Serial</code> annotation is one of the defined serialization-related * methods declared in a meaningful context. * * <p>It is a semantic error to apply this annotation to other fields or methods, including: * <ul> * <li>fields or methods in a class that is not {@code Serializable} * * <li>fields or methods of the proper structural declaration, but in * a type where they are ineffectual. For example, {@code enum} types * are defined to have a {@code serialVersionUID} of {@code 0L} so a * {@code serialVersionUID} field declared in an {@code enum} type is * ignored. The five serialization-related methods identified above * are likewise ignored for an {@code enum} type. * * </ul> */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.SOURCE) public @interface Serial { }
-- - DML
Hi David, On 5/10/2018 1:39 PM, David Lloyd wrote:
Would it be allowed to enable the serial lint without using the @Serial annotation?
Certainly. A limited serial lint checker already exists in javac and we enable that check it in the JDK build. Basically it checks that a serializable class defines a static final serialVersionUID field. The expanded checks I have planned for JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods" for do various additional checks even without @Serial annotation being used. Without the annotation, the lint checks could verify that if a field or method with one of the designated names is present in a serializable class, it is declared properly, catching bad method overloads, etc. In addition, it could catch ineffective serial-related fields and methods in an enum, etc. HTH, -Joe
On Thu, May 10, 2018 at 7:52 PM, joe darcy <joe.darcy@oracle.com> wrote:
Hi David,
On 5/10/2018 1:39 PM, David Lloyd wrote:
Would it be allowed to enable the serial lint without using the @Serial annotation?
Certainly.
A limited serial lint checker already exists in javac and we enable that check it in the JDK build. Basically it checks that a serializable class defines a static final serialVersionUID field.
The expanded checks I have planned for JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods" for do various additional checks even without @Serial annotation being used. Without the annotation, the lint checks could verify that if a field or method with one of the designated names is present in a serializable class, it is declared properly, catching bad method overloads, etc. In addition, it could catch ineffective serial-related fields and methods in an enum, etc.
Great. Then it's a +1 from me, FWIW. -- - DML
On 10/05/2018 16:55, joe darcy wrote:
Hello,
Please review the webrev (code below) to address
JDK-8202385: Annotation to mark serial-related fields and methods http://cr.openjdk.java.net/~darcy/8202385.0/ I see the exchange with Roger about Externalizable and I think the wording looks good too. Also I agree source retention is right (and consistent with @Override).
-Alan
participants (4)
-
Alan Bateman
-
David Lloyd
-
joe darcy
-
Roger Riggs