Archive for August, 2011

31
Aug
11

Backward compatibility Object Serialization in Java

Breaking object-serialization in Java is easy. Just change some fields in the used DTOs transfered via network and whooopp its broken.

I came along this topic as i tried some openjdk contribution.

The contribution was to same exceptions that are extending RuntimeException but not supporting the 2 conventional constructors with the exception cause.

There are 10 Exception where i found a seperate cause field.

1. javax/xml/crypto/NoSuchMechanismException.java:    private Throwable _exception;
2. javax/security/sasl/SaslException.java:    private Throwable _exception;
3. java/lang/reflect/UndeclaredThrowableException.java:    private Throwable undeclaredThrowable;
4. java/lang/reflect/InvocationTargetException.java:    private Throwable target;
5. java/lang/ClassNotFoundException.java:    private Throwable ex;
6. com/sun/java/browser/dom/DOMAccessException.java:    private Throwable ex;
7. com/sun/java/browser/dom/DOMUnsupportedException.java:    private Throwable ex;
8. javax/naming/NamingException.java:    protected Throwable rootException = null;
9. java/rmi/RemoteException.java:    public Throwable detail;
10. java/rmi/activation/ActivationException.java:    public Throwable detail;

Nr. 1 was the first i have looked at. My first attempt was to just remove the cause field add the missing constructors and remove the unnessacery methods for printing the stacktrace. But this definitly break serialisation compatibility. The serialversionUID is the same but the serialization content is missing the cause field.

My second attempt was to add the cause field in serialization manually through introducing something like this.

  65     private static final ObjectStreamField[] serialPersistentFields = {
  66         new ObjectStreamField("cause", Throwable.class)};
 114     private void readObject(ObjectInputStream stream)
 115             throws IOException, ClassNotFoundException {
 116         initCauseFieldFromSerializationStream(stream, "cause");
 117     }
 118
 119     private void writeObject(ObjectOutputStream stream)
 120             throws IOException {
 121         writeCauseAsAPrivateField(stream, "cause");
 122     }

While introducing the following in Throwable.java

1097     protected void initCauseFieldFromSerializationStream(ObjectInputStream stream, String oldFieldName) throws ClassNotFoundException, IOException {
1098         GetField readFields = stream.readFields();
1099         Throwable cause = (Throwable) readFields.get(oldFieldName, this);
1100         /* If there is a cause that is deserialized and there is no cause
1101          * set in Throwable.cause (== null means serialized prior jdk8)
1102          * then initialize cause. There is another implicit functionality here:
1103          * If Throwable.cause is initialized yet(since jdk8) and
1104          * this.getCause() != cause then there is something is rotten in the
1105          * state of Denmark. Calling initCause in this situation will result
1106          * in an exception
1107          */
1108         if (cause != null && this.getCause() != cause) {
1109             // If cause is
1110             initCause(cause);
1111         }
1112     }
1131     protected void writeCauseAsAPrivateField(ObjectOutputStream stream, String oldFieldName) throws IOException {
1132         PutField putFields = stream.putFields();
1133         if (this.getCause() != null) {
1134             putFields.put(oldFieldName, this.cause);
1135         }
1136         stream.writeFields();
1137     }

This might be ok. But it is somewhat the otherway around this problem is solved already in
the other cases mentioned above. The other solution leaves the cause field but utilizes the
functionality of chaining in Throwable in an much easier fashion.

But this will be part of another post.

20
Aug
11

OpenJDK Contributions

After i have contributed to openjdk7 same time ago and followed the JAVA 7 Launch i decided to continue contributing to openjdk.

But where to start. I didn’t followed openjdk developement since my contribution. So i started reading the mailing-lists.

After some minor reviews and comments i started some small projects to start contributing code again.

  1. Chain Exceptions more consequently
  2. Reduce Warnings
  3. and maybe Iterable support for Enumerations

While Project 3 is not yet started. Project 1 and 2 are running.

Chain Exceptions more consequently

I started with InternalError because i found some amount of places where new InternalError().initCause(ex) is used instead of chaining rootcause via ctor-parameter. After i changed InternalError and it’s supertyp itself i changed the places where initCause where called. After that i searched for every instantiation of InternalError with the “old” ctors and looked if i can chain with some root-cause. This is not an really complex task but it takes some time to do it.

After that i started over with RuntimeException. Again search instantiation with the old ctors. Chain Exception where possible. Maybe i introduce some performance issues with this. But i don’t really think so.

While checking if all is compiling after my changes i ran into an problem with new warnings. But after some questions in the mailing list and a clean make it was gone. I checked if i introduce new warnings through my changes and found that there a some warnings in existing code that can be fixes without much effort.

Reduce Warnings

There where places where a varargs argument doen’t match Object[] or Object. Example: if you submit String[] to an vararg-argument you can some warnings, because the compiler can not figure out if you want to submit an simgle Object or if you want to submit various String to the varargs-argument. An cast to Object or Object[] does the trick.

The second warning type that can be fixed easily is unnecessary cast. Just remove the cast and it’s done.

How to submit to openjdk?

I created a free hosting account. And uploaded the webrevs to it. Here are my actual webrevs for openjdk

Contributions run running thought the mailing list with public review. I hope to get some good feedback.

18
Aug
11

On the road again

Welcome to my Weblog.

I the near future you will read at CodingWizard.wordpress.com all i get along by my coding adventures.

Hope to have some news soon.

- CodingWizar




Follow

Get every new post delivered to your Inbox.