user3081347
user3081347

Reputation: 33

readObject method of objectinputstream throw ClassNotFoundException when changed class package

I used ObjectOutputStream to wirte object keeping object of properties in computer. Unfortunately I get ClassNotFoundException when changed to class package name at special cases.

That important of my question is:

How can I get old properties in old class into the my changed class?

I have to resolve issue because I need old properties to keeping my applications is work.I'm sure properties are same correctly that only class name is different.

Upvotes: 3

Views: 1958

Answers (2)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136012

There is a workaround:

class Workaround extends ObjectInputStream {
    String className;

    public Workaround(InputStream in, Class<?> cls) throws IOException {
        super(in);
        this.className = cls.getName();
    }

    @Override
    protected ObjectStreamClass readClassDescriptor() throws IOException,
            ClassNotFoundException {
        ObjectStreamClass cd = super.readClassDescriptor();
        try {
            Field f = cd.getClass().getDeclaredField("name");
            f.setAccessible(true);
            f.set(cd, className);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return cd;
    }
}

Now I can write an instance of Test1 and read it as an instance of Test2

class Test1 implements Serializable {
    private static final long serialVersionUID = 1L;
    int i;
}

class Test2 implements Serializable {
    private static final long serialVersionUID = 1L;
    int i;
}

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("1"));
Test1 test1 = new Test1();
oos.writeObject(test1);
oos.close();
Workaround x = new Workaround(new FileInputStream("1"), Test2.class);
Test2 test2 = (Test2)x.readObject();

Upvotes: 3

user207421
user207421

Reputation: 310913

Unfortunately I get ClassNotFoundException when changed to class package name at special cases

Change it back. You can change a lot of things about a class without breaking existing serializations, but the package name isn't one of them. You need to study the Versioning of Serializable Objects chapter of the Object Serialization Specification to see what you can and cannot change. It's too late to have second thoughts about package names after you've already done some serializations, indeed after you've deployed your application. Leave it be.

There are other ways around this but I'm hoping you won't need them.

Upvotes: 2

Related Questions