Objective
To highlight XMLEncoder class issue with java.sql.Timestamp class in JDK 5 and 6.
Environment
Java 5 and 6
Issue
From Java 5 we have XMLEncoder and XMLDecoder class to deal with XML encoding and decoding; but if you have observed the java.sql.Timestamp class is not taken care correctly by these classes, the following example is to show the same:
Program
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.Timestamp;
import java.util.Date;
/**
* @author mchopker
*
*/
public class TestXMLEnocdingIssue {
public static void main(String[] args) {
try {
XMLEncoder enc = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream("Test.xml")));
Person person = new Person("Mahesh", new Timestamp(
new Date().getTime()));
enc.writeObject(person);
enc.close();
System.out.println("Encoding completed....");
} catch (Exception e) {
e.printStackTrace();
}
try {
XMLDecoder dec = new XMLDecoder(new BufferedInputStream(
new FileInputStream("Test.xml")));
Object result = dec.readObject();
dec.close();
System.out.println(result);
System.out.println("Decoding completed....");
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.Timestamp;
import java.util.Date;
/**
* @author mchopker
*
*/
public class TestXMLEnocdingIssue {
public static void main(String[] args) {
try {
XMLEncoder enc = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream("Test.xml")));
Person person = new Person("Mahesh", new Timestamp(
new Date().getTime()));
enc.writeObject(person);
enc.close();
System.out.println("Encoding completed....");
} catch (Exception e) {
e.printStackTrace();
}
try {
XMLDecoder dec = new XMLDecoder(new BufferedInputStream(
new FileInputStream("Test.xml")));
Object result = dec.readObject();
dec.close();
System.out.println(result);
System.out.println("Decoding completed....");
} catch (Exception e) {
e.printStackTrace();
}
}
}
---
import java.io.Serializable;
import java.sql.Timestamp;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Timestamp time;
public Timestamp getTime() {
return time;
}
public void setTime(Timestamp time) {
this.time = time;
}
public Person() {
}
public Person(String string, Timestamp time) {
this.name = string;
this.time = time;
}
public String getName() {
return name;
}
public void setName(String string) {
this.name = string;
}
}
Console Output
java.lang.InstantiationException: java.sql.Timestamp
Continuing ...
java.lang.RuntimeException: failed to evaluate: <unbound>=Class.new();
Continuing ...
Encoding completed....
Person@6bdd46f7
Decoding completed....
Continuing ...
java.lang.RuntimeException: failed to evaluate: <unbound>=Class.new();
Continuing ...
Encoding completed....
Person@6bdd46f7
Decoding completed....
XML Output
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_15" class="java.beans.XMLDecoder">
<object class="Person">
<void property="name">
<string>Mahesh</string>
</void>
</object>
</java>
Observation
You can notice the exception shown as red color text, this is thrown by Java itself and the resulting XML not containing the timestamp attribute; the reason java.sql.Timestamp class is not taken care by Java 5/6 and is fixed now in Java 7.
If you still happens to use Java 5/6 for some reason then you might have to write custom persistence delegate to deal with this issue as mentioned here:
No comments:
Post a Comment