Convert outdated stored class to updated class - java

I am facing a problem with the classes. I store data in Serializable classes as a Java Object, not as a series of variables at some places. However, when I make changes to the class in question, Java would immediately throw an Error.
For example this is an old class:
class Demo implements Serializable{
private int a; private int b; int c;
public void doSomething(){}
public void doSomethingElse(){}
}
Which gets updated to:
class Demo implements Serializable{
private int a; private private int b; private int c; private String x; private String y; private String z;
public void doSomething(){}
public void doSomethingElse(){}
public void doAnotherThing(){}
public void doYetAnotherThing(){}
}
Is there a way to convert the old Object to the new one seamlessly without having to name the new class as DemoNew or something and then transferring the values one by one?
Regards.

That's what the serialVersionUID is for. If you declare it in your new class, and it has the same value as it had when the object was serialized, then Java will know that the new class is still compatible with the old class, and will initialize a, b, and c (and will leave the other fields to their default value).
So, get the old serialVersionUID from the error being thrown, and add this field to the class:
private static final long serialVersionUID = ...;
Of course, that only works if the new class is effectively still compatible with the old one. If you renamed or removed fields, then you'll have to make it compatible by explicitely reading the object as it was at the time of serialization.
If I were you, I would stop using serialization as a long-term persistence mechanism. Choose an easily migratable format instead: a database, JSON, or XML for example.

Related

Serialization and Deserialization with extra variable in client side but same version id

Say I have class A in server side with two variables.
class A implements Serializable {
public static final long serialVersionUID = 1234;
String a;
String b;
}
In client side I have same class with three variables but same version id.
class A implements Serializable {
public static final long serialVersionUID = 1234;
String a;
String b;
String c;
}
What happens here? bit confused about its behaviour.
This is a stream-compatible change. The extra value will be thrown away if received by the side that doesn't have it, or set to its default value at the side that does have it if sent from the side that doesn't have it.

Proper way to use Final Field in RealmObject

I wanted to use final field in RealmObject like private final int fieldName. Because, I want to use constants and methods efficiently.
CleanTime.java
public class CleanTime extends RealmObject {
private final int NIGHT_TIME_LECTURE_MINUTE_LENGTH = 50;
private final int NIGHT_TIME_LECTURE_BREAK_TIME_MINUTE = 10;
// and other field
public CleanTime() {
// Constructor which use NIGHT_TIME_LECTURE_MINUTE_LENGTH
}
// and other methods
}
But the problem is my Logcat throws the error which said "this class contains illegal final field"
So, I had found some documents about realm and got the reason why it doesn't work.
In Realm official document..
Currently, Realm models have no support for final, transient and volatile fields. This is mainly to avoid discrepancies between how an object would behave as managed by Realm or unmanaged.
So, I have tried to solving this problem and below codes are completed which is using Instance Initializer
CleanTime.java
public class CleanTime extends RealmObject {
private int NIGHT_TIME_LECTURE_MINUTE_LENGTH;
private int NIGHT_TIME_LECTURE_BREAK_TIME_MINUTE;
// and other field
{ // Instance Initializer
NIGHT_TIME_LECTURE_MINUTE_LENGTH = 50;
NIGHT_TIME_LECTURE_BREAK_TIME_MINUTE = 10;
}
public CleanTime() {
// Constructor which use NIGHT_TIME_LECTURE_MINUTE_LENGTH
}
// and other methods
}
But I am curious whether this is proper, realm recommened way to use final field. Am I doing right? Is there any better idea?
Ah, above codes is same as NIGHT_TIME_LECTURE_MINUTE_LENGTH = 50 I want to fix NIGHT_TIME_LECTURE_MINUTE_LENGTH field and don't want it to be changed

What is the correct way to initialize fields of Action classes in Struts 2?

I have a class which I am using to store data that I retrieve from a database which has objects as fields.
I want to initialize the objects when the class is instantiated to avoid null pointer problems.
I thought I read somewhere that it should not initialize the fields in the field declaration because it may cause problems for Struts (but I can't find the statement now), so I am initializing the fields in the constructor.
My question is:
Does it matter which way you do it? Or should you not do it at all and only put in the new objects after you instantiate the class? In other words should I define my class like this:
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(){
projectInfo = new ProjectInfo();
partyInfo = new PartyInfo();
requestTableInfo = new RequestTableInfo();
partyRequestInfo = new PartyRequestInfo();
}
followed by getters and setters or like this.
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo = new ProjectInfo();
private PartyInfo partyInfo = new PartyInfo();
private RequestTableInfo requestTableInfo = new RequestTableInfo();
private PartyRequestInfo partyRequestInfo = new PartyRequestInfo();
public MenuView(){ }
followed by getters and setters or like this:
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(){}
followed by getters and setters and then instantiate it like this:
MenuView menu = new MenuView();
menu.setProjectInfo(new ProjectInfo);
Any of the methods above would work but this would be best. The whole point of initializing a class is to avoid null referenced of course and initialize them with preferred values as shown below.
Adding getters and setters would work just fine from there
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(int a, int b, int c, int d){
projectInfo = new ProjectInfo(a);
partyInfo = new PartyInfo(b);
requestTableInfo = new RequestTableInfo(c);
partyRequestInfo = new PartyRequestInfo(d);
}
I read somewhere that you should not initialize the fields in the field declaration because that may cause problems for Struts (but I can't find the statement now)
No, not that I know
so I am initializing the fields in the constructor.
You can, but you're not forced to. I never use constructors on actions (I almost never use constructors at all, since I'm using Java EE 6+ and CDI, and in constructors the #Injected objects have not been injected yet - I use a #PostConstruct method instead, when necessary), but that's up to you, it's not a rule.
My question is does it matter which way you do it?
No
Or should you not do it at all and only put in the new objects after you instantiate the class?
Struts2 will handle the nulls for you in the JSP. The only NullPointerExceptions you must handle are on the Java side, so just check for null, or instantiate the objects in the declaration, and don't worry about it anymore.
Just remember that Struts2 will need a no-arg constructor to instantiate beans with JSP values.
It doesn't matter for Struts2, only sufficient that a ModelDriven object you should create yourself (if you are using ModelDriven interface).
The framework will create the objects if they are null when the form is submitted. This option is enabled by default. The magic is performed by the params interceptor which is using OGNL under hoods to populate the model from parameters passed to the action.
While this interceptor is being invoked, a flag
(ReflectionContextState#CREATE_NULL_OBJECTS) is turned on to ensure
that any null reference is automatically created - if possible. See
the type conversion documentation and the InstantiatingNullHandler
javadocs for more information.
More or less this feature is documented under com.opensymphony.xwork2.conversion.NullHandler.
The beans should comply a JavaBeans spec., so they could be instantiated by the Struts2 framework (if you want to learn more about JavaBeans, see this post What is a JavaBean exactly).

Overriding class signature in java

I have a class as follows in a .jar file (library file):
class A{
//someimplementation
}
I would like to make it to implements Serializable interface as follows:
class A implements Serializable {
//the same implementation as present in classA
}
I do not want to decompile the jar file, changing the class signature and then archiving it again after compilation.
Is there any way like writing hooks to achieve this? Kindly provide any pointers/suggestions.
My ultimate aim is to achieve implementing Serializable interface without modifying the jar file.
You can probably achieve this using Serialization Proxy Pattern (Effective Java 2nd edition Item 78)
A few links about the Pattern :
http://jtechies.blogspot.com/2012/07/item-78-consider-serialization-proxies.html
http://java.dzone.com/articles/serialization-proxy-pattern
Follow up: instance control in Java without enum
Make a new class that extends A and is Serializable. In order to avoid serialization errors, however, because A isn't serializable, you need to make a SerializationProxy that creates a new instance via constructor or factory method instead of the normal Java Serialization mechanism of explicitly setting the fields outside of any constructor.
public class MySerializableA extends A implements Serializable{
private final Foo foo;
private final Bar bar;
...
private Object writeReplace() {
return new SerializationProxy(this);
}
//this forces us to use the SerializationProxy
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use Serialization Proxy instead.");
}
//this private inner class is what actually does our Serialization
private static class SerializationProxy implements Serializable {
private final Foo foo;
private final Bar bar;
...
public SerializationProxy(MySerializableA myA) {
this.foo = myA.getFoo();
this.bar = myA.getBar();
...//etc
}
private Object readResolve() {
return new MySerializableA(foo, bar,...);
}
}
}
The only downside is when you want to serialize an A, you will have to wrap it in a MyA. but when deserializing, the cast to A will work fine.

Java: about Collections ReverseComparator implementation

This is implemented as follows (jdk1.6.0_31):
private static class ReverseComparator<T>
implements Comparator<Comparable<Object>>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c2.compareTo(c1);
}
private Object readResolve() { return reverseOrder(); }
}
Why can't it instead be implemented as follows:
private static class ReverseComparator<T extends Comparable<T>>
implements Comparator<T>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare(T c1, T c2){
return c2.compareTo(c1);
}
...
}
Is it just style, or is there some deeper reason?
EDIT: the source code shown is from Sun/Oracle jdk ((jdk1.6.0_31)).
I believe it is all related to the intention of making of ReverseComparator a singlenton object. Since the singlenton instance has to be defined in a static context there is no point in using any generic types.
static final ReverseComparator REVERSE_ORDER = new ReverseComparator();
This code, generates a raw type warning.
As such, the implementation of ReverseComparator, which is only used for this matter, could have been as you suggested or as it was implemented. Perhaps they chose the current implementation because it is easier to read, and because they thought that further generalization was not needed if it was only going to be privately used for this simple purpose.
Running the Java decompiler over your implementation and over the Oracle's implementation produces the same raw type byte codes.
public int compare(java.lang.Comparable, java.lang.Comparable
public int compare(java.lang.Object, java.lang.Object);
At the end, when the comparator is exposed through the public interface of the Collections class in the reverseOrder() method, it is impossible to avoid the casting and the unchecked warning. But we all are sure that this cannot fail, regardless of types involved.
Bottom line, IMHO I think the only reason why it was implemented as it was has to do with code clarity, or with the desire of not complicating the things more than necessary if, anyways, the unchecked warning could not be prevented. But hey, this wouldn't be the first time I am wrong ;-)
Just guessing, but it's stored in a static field
static final ReverseComparator REVERSE_ORDER
= new ReverseComparator();
so your version would generate a 'raw types' warning.
I'm looking at Oracle 1.6.0_26, but I see the same code. As far as I can tell, those are functionally equivalent. You could also potentially write it like this:
private static class ReverseComparator<T> implements Comparator<Comparable<T>>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare( Comparable<T> c1, Comparable<T> c2 ) {
return c2.compareTo( (T) c1 );
}
private Object readResolve() {
return reverseOrder();
}
}
My only guess as to why they did it using Comparable<Object> is based on the fact that classes that implement Comparable (or Comparator) should obey the equals()contract, which does use Object. So semantically, this emphasizes that connection. Other than that, I can't think of a reason why.

Categories