Stuart,

Sorry, but such inconsistency between serialver/javap is a bug (IMHO, of 
course).

> If there happens to be a declaration in the class that, probably mistakenly, 
> goes against this advice, serialver shouldn't emit a line that perpetuates 
> this mistake.

I would argue that for any real-life API it's almost impossible to fix such 
explicitly-defined "bad"  (i.e. public/protected) SVUID in any compatible way,  
so emitting 'private'  will not help there, unfortunately. 

-Yuri

-----Original Message-----
From: Stuart Marks [mailto:stuart.ma...@oracle.com] 
Sent: Friday, November 8, 2013 10:48 PM
To: Yuri Gaevsky
Cc: Alan Bateman; core-libs-dev
Subject: Re: 8028027: serialver should emit declaration with the 'private' 
modifier

On 11/8/13 7:20 AM, Yuri Gaevsky wrote:
>> Well, it would be more consistent to check for existence of protected or 
>> public serialVersionUID with Reflection API and change the serialver output 
>> accordingly.
>
> Please see suggested fix and its output below.

This change isn't consistent with the intent of the 'serialver' utility. Its 
intent is to produce a declaration that's "suitable for copying into an 
evolving class." [1] (Clearly, this means the source code of a class.) The spec 
[2] "strongly advises" that serialVersionUID be private. As such, serialver 
should follow the strong advice given in the spec.

If there happens to be a declaration in the class that, probably mistakenly, 
goes against this advice, serialver shouldn't emit a line that perpetuates this 
mistake.

One can use "javap -v" to determine the presence of serialVersionUID field, 
including its modifiers, if that's what's desired.

s'marks

[1] http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/serialver.html

[2] http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

>

> Thanks,
> -Yuri
>
> $ serialver java.security.PublicKey
> java.security.PublicKey:    public static final long serialVersionUID = 
> 7187392471159151072L;
>
> $ serialver java.lang.Exception
> java.lang.Exception:     static final long serialVersionUID = 
> -3387516993124229948L;
>
> $ serialver java.lang.AssertionError
> java.lang.AssertionError:    private static final long serialVersionUID = 
> -5013299493970297370L;
>
> $ serialver javax.xml.ws.soap.SOAPFaultException
> javax.xml.ws.soap.SOAPFaultException:    private static final long 
> serialVersionUID = -104968645459360720L;
>
>
> $ hg diff
> diff --git a/src/share/classes/sun/tools/serialver/SerialVer.java 
> b/src/share/classes/sun/tools/serialver/SerialVer.java
> --- a/src/share/classes/sun/tools/serialver/SerialVer.java
> +++ b/src/share/classes/sun/tools/serialver/SerialVer.java
> @@ -38,6 +38,7 @@
>   import java.net.MalformedURLException;
>   import java.util.StringTokenizer;
>   import sun.net.www.ParseUtil;
> +import java.lang.reflect.Modifier;
>
>   public class SerialVer extends Applet {
>       GridBagLayout gb;
> @@ -211,7 +212,17 @@
>           Class<?> cl = Class.forName(classname, false, loader);
>           ObjectStreamClass desc = ObjectStreamClass.lookup(cl);
>           if (desc != null) {
> -            return "    static final long serialVersionUID = " +
> +           String ams = "";
> +           try {
> +               final int mod =
> +                       
> cl.getDeclaredField("serialVersionUID").getModifiers();
> +               ams = Modifier.isPublic(mod) ? "public"
> +                   : Modifier.isProtected(mod) ? "protected"
> +                   : Modifier.isPrivate(mod) ? "private" : "";
> +           } catch (NoSuchFieldException nsfe) {
> +               ams = "private";
> +           }
> +            return "    " + ams + " static final long serialVersionUID = " +
>                   desc.getSerialVersionUID() + "L;";
>           } else {
>               return null;
>

Reply via email to