We work heavily with serialization and having to specify Serializable tag on every object we use is kind of a burden. Especially when it's a 3rd-party class that we can't really change.
The question is: since Serializable is an empty interface and Java provides robust serialization once you add implements Serializable - why didn't they make everything serializable and that's it?
What am I missing?
Serialization is fraught with pitfalls. Automatic serialization support of this form makes the class internals part of the public API (which is why javadoc gives you the persisted forms of classes).
For long-term persistence, the class must be able to decode this form, which restricts the changes you can make to class design. This breaks encapsulation.
Serialization can also lead to security problems. By being able to serialize any object it has a reference to, a class can access data it would not normally be able to (by parsing the resultant byte data).
There are other issues, such as the serialized form of inner classes not being well defined.
Making all classes serializable would exacerbate these problems. Check out Effective Java Second Edition, in particular Item 74: Implement Serializable judiciously.
I think both Java and .Net people got it wrong this time around, would have been better to make everything serializable by default and only need to mark those classes that can't be safely serialized instead.
For example in Smalltalk (a language created in 70s) every object is serializable by default. I have no idea why this is not the case in Java, considering the fact that the vast majority of objects are safe to serialize and just a few of them aren't.
Marking an object as serializable (with an interface) doesn't magically make that object serializable, it was serializable all along, it's just that now you expressed something that the system could have found on his own, so I see no real good reason for serialization being the way it is now.
I think it was either a poor decision made by designers or serialization was an afterthought, or the platform was never ready to do serialization by default on all objects safely and consistently.
Not everything is genuinely serializable. Take a network socket connection, for example. You could serialize the data/state of your socket object, but the essence of an active connection would be lost.
The main role of Serializable in Java is to actually make, by default, all other objects nonserializable. Serialization is a very dangerous mechanism, especially in its default implementation. Hence, like friendship in C++, it is off by default, even if it costs a little to make things serializable.
Serialization adds constraints and potential problems since structure compatibility is not insured. It is good that it is off by default.
I have to admit that I have seen very few nontrivial classes where standard serialization does what I want it to. Especially in the case of complex data structures. So the effort you'd spend making the class serializble properly dwarves the cost of adding the interface.
For some classes, especially those that represent something more physical like a File, a Socket, a Thread, or a DB connection, it makes absolutely no sense to serialize instances. For many others, Serialization may be problematic because it destroys uniqueness constraints or simply forces you to deal with instances of different versions of a class, which you may not want to.
Arguably, it might have been better to make everything Serializable by default and make classes non-serializable through a keyword or marker interface - but then, those who should use that option probably would not think about it. The way it is, if you need to implement Serializable, you'll be told so by an Exception.
I think the though was to make sure you, as the programmer, know that your object my be serialized.
Apparently everything was serializable in some preliminary designs, but because of security and correctness concerns the final design ended up as we all know.
Source: Why must classes implement Serializable in order to be written to an ObjectOutputStream?.
Having to state explicitely that instances of a certain class are Serializable the language forces you to think about if you you should allow that. For simple value objects serialization is trivial, but in more complex cases you need to really think things through.
By just relying on the standard serialization support of the JVM you expose yourself to all kinds of nasty versioning issues.
Uniqueness, references to 'real' resources, timers and lots of other types of artifacts are NOT candidates for serialization.
Read this to understand Serializable Interface and why we should make only few classes Serializable and also we shopuld take care where to use transient keyword in case we want to remove few fields from the storing procedure.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
Well, my answer is that this is for no good reason. And from your comments I can see that you've already learned that. Other languages happily try serializing everything that doesn't jump on a tree after you've counted to 10. An Object should default to be serializable.
So, what you basically need to do is read all the properties of your 3rd-party class yourself. Or, if that's an option for you: decompile, put the damn keyword there, and recompile.
There are some things in Java that simply cannot
be serialized because they are runtime specific. Things like streams, threads, runtime,
etc. and even some GUI classes (which are connected to the underlying OS) cannot
be serialized.
While I agree with the points made in other answers here, the real problem is with deserialisation: If the class definition changes then there's a real risk the deserialisation won't work. Never modifying existing fields is a pretty major commitment for the author of a library to make! Maintaining API compatibility is enough of a chore as it is.
A class which needs to be persisted to a file or other media has to implement Serializable interface, so that JVM can allow the class object to be serialized.
Why Object class is not serialized then none of the classes need to implement the interface, after all JVM serializes the class only when I use ObjectOutputStream which means the control is still in my hands to let the JVM to serialize.
The reason why Object class is not serializable by default in the fact that the class version is the major issue. Therefore each class that is interested in serialization has to be marked as Serializable explicitly and provide a version number serialVersionUID.
If serialVersionUID is not provided then we get unexpected results while deserialzing the object, that is why JVM throws InvalidClassException if serialVersionUID doesn't match. Therefore every class has to implement Serializable interface and provide serialVersionUID to make sure the Class presented at the both ends is identical.
Question/Problem
Given a plain Java class coming from a non-EMF-aware API such as
public class BankAccount {
String ownerName;
int accountNumber;
// ...
}
and also let's assume that I am not allowed to change or recompile this class (because it is from an API).
Is there any simple way to use this class as an ESuperType for an EClass in EMF? (And, of course, the single class is just an example. I'd need to wrap an API consisting of 30-50 classes ...).
Own thoughts
Personally, I think it is not possible out of the box.
I could only think of two ways, both with quite some effort and not easy to realize.
Create an Ecore model which reflects the original class (EBankAccount, having ownerName and accountNumber as EAttributes) and a utility method/mechanism that wraps the original object by copying its fields into the corresponding EStructuralFeatures and adds EAdapters which are responsible to synchonize both objects.
Hook into EMF.CodeGen and do some magic there which makes it possible to have the original class as super class in the generated code which at the same time still fulfilling the EMF contract (= implement the EObject interface etc.).
But maybe there's some hidden feature of EMF (or an existing extension) which does something along these lines, and I am not aware of it?
It's not clear to me what you real want, but I will try to describe the several options.
If you want just to extend the POJO (which is what the question text suggests), the answer is YES, you can simply add a new EClass to your model and refer to the POJO qualified name in the "Instance Type Name" attribute. Then you can create other classes that extend from this one, but its state won't be managed by EMF.
But if you want EMF to track that POJO state as if it was a real EMF object (so those properties are also EStructuralFeature), then I don't see another solution, you really need to model it completely in EMF.
In this second case, both options you described seem possible.
The first option you described (and I assume you mean you want to synchronize the 2 objects, and not the 2 classes) seems the easiest one, and I don't think it would take so much effort if you use some generic method via reflection.
This might be a good solution if you get the objects in very concrete locations, so you only need to wrap and unwrap in specific places. Otherwise you will need to convert be converting (wraping/unwrapping) the object all the time.
It may be also possible but it requires more effort for sure, since it's not easy to extend the Java JET templates
I'm not aware of any extension for this.
Why can't just avoid this if I want all objects in my app to be serializable ?
Update: I know that some class cannot be serialized like thread but the java system KNOWS also that Thread is not serializable, why doesn't it manage this automatically ?
I'd like to know if there are some fundamental reasons.
Why can't just avoid this if I want all objects in my app to be serializable ?
Simply, because that's the way Java serialization works.
Consider that it does not make sense to serialize all objects.
Thread instances and instances of most Stream classes include critical state that simply cannot be serialized.
Some classes depend on class statics, and they are not serialized.
Some classes are non serializable because they critically depend on unserializable classes.
Some classes you simply don't want or need to serialize.
So given that, how should the application programmer control what gets serialized? How does he stop all sorts of unnecessary stuff from being serialized by accident? Answer: by declaring the classes he wants to be serializable as implementing Serializable.
If you implement all your serialization-related code yourself, you don't need it, but as long as you do it using standard library functions, there must be some way to communicate that your classes are designed and ready for serialization. Just because all the classes in your program are serializable doesn't mean they are in other's programs.
Because that's the way the language was designed? Questions like this are fundamentally pointless. It would have been possible, and indeed easier, to make all classes serializable, but it wasn't done that way. There are lots of reasons why not, and they are given in some FAQ or Gosling interview somewhere, that I read about 12 years ago. Security was certainly one of them. But at this stage it's a futile discussion really.
I want to write an object into a stream (or byte array) with its transient attributes to be able to reconstruct it in another VM. I don't want to modify its attributes because that object is a part of legacy application.
Standard Java serialization mechanism doesn't help. What other options do I have?
Update:
The reason I'm asking the question is that I want to modify an existing Spring application. It called a bean's method in-process earlier but now I want to move the bean on a separate machine and use Spring remoting through HTTP invoker. And I have a problem with parameters that have transient fields that need to be passed to this method but not needed to be serialized in other parts of the app.
Hmm - if an attribute is marked as transient, that means exactly that it's not mean to be considered part of the object's persistent state, e.g. for serialization. The fact that you want to do this at all is a code smell, and the correct solution is to stop those fields being transient.
Let's say though that for whatever reason you can't modify the target classes themselves. My first thought was that you could customise the serialisation by implementing readObject() and writeObject() methods, but that would also require changes to the target class.
In that case, you'll need to work with some kind of reflection-based or metadata-based API in order to do this. There are many libraries that will convert objects to and from XML or JSON or DB rows, etc. Your best bet would be to use one of these to convert the object to and from "hydrated" form (and likely you'll need to customise them, as any sane serialiser will ignore transient fields). Which one to pick depends on your current software stack, and your precise requirements.
I assume you cannot change the legacy code. In this case I think you will have to resort to going over the object fields with reflection and DataOutputStream.
transient variables are supposed to be those that aren't serializable or are easily recalculated.
My first suggestion is to look for methods on this object to recalculate the transient fields.
In general, is it a best practice to have simple POJO Java classes implement java.io.Serializable?
Generally not. Joshua Bloch says to implement Serializable judiciously. A summary of drawbacks that he describes:
decreases flexibility of changing class implementation later - the serialized form is part of the class's API
makes some bugs and security holes more likely - an attacker can access class internals within the serialized byte stream
increases test burden - now you have to test serialization!
burdens authors of subclasses - they have to make their subclasses Serializable too
Of course, sometimes you need a POJO to implement Serializable, say for RMI, but if the need isn't there, your code will be simpler and more secure without it.
Only if you need to be able to serialise them. It's not worth the effort otherwise.
It depends more on the needs. In the context of web applications, some web servers (eg. Tomcat 6) even make it mandatory to serialize the classes whose objects we store in sessions.
One thing I've done to address the fact that the serialized form is not backwards compatible (say when dynamically reloading a class on a running system), is load the fields I want to save into a hashmap and then serializing that. That way, I can always deserialize in the data, even if there are missing fields. You might have to provide defaults for missing keys, but it's better than messing up field order.