This question already has answers here:
Java Serialised object vs Non serialised object
(4 answers)
Closed 8 years ago.
As per serialization definition it is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment.
Everything is clear from the definition except trasfering object over network. Is serialization is the only way for a java object to get transfered over netowrk?
In context of webapp there are many pojo classes which does not implement serializable interface but still we access objects of those classes from client. Does app servers or JVM handles serialization for these classes?
Your classes don't really need to implement Serializable in order to transfer them across the network, because there are a lot of different forms of serialization and java's built-in one is actually not so great. Why ? Because the receiving end must also be a java application and it must have a compatible version of the class you are transferring.
More portable and flexible way of transferring your data across the network is to marshal them to XML/JSON, which can be consumed from any system, no matter whether it's java, c++, python or anything else (and as you have might already guessed - the objects do not need to implement Serializable in order to be (un)marshalled from/to to XML,Json, etc.).
Also there are a lot of other serialization frameworks which are accomplishing this task much better than the java's built-in serialization mechanism. An example would be: Google's Protobuff, Apache Thrift, Avro, Kryo and many other.
In context of webapp there are many pojo classes which does not implement serializable interface but still we access objects of those classes from client. Does app servers or JVM handles serialization for these classes?
No, this is handled by the application, or by the framework you are using. For example Jax-RS implementations would use some library like Jakson to marshal the objects to/from Xml/Json behind the scenes.
Serializable is required for objects stored in your session, if you want to use persistent (surviving app server restarts) and/or shared (across multiple app servers) sessions.
Data transfer to clients is usually not done by Java serialization (JSON/XML), as others have already explained.
Related
There is this Sonar rule called Fields in a “Serializable” class should either be transient or serializable. It comes up when you add a non-serializable field to your class. The rule states:
For instance, under load, most J2EE application frameworks flush objects to disk, and an allegedly Serializable object with non-transient, non-serializable data members could cause program crashes, and open the door to attackers.
This sounds outdated to me. In Effective Java 3rd Edition it is stated that Serialization is not relevant, when developing new software. Also, Removing Serialization from Java Is a 'Long-Term Goal' at Oracle. The Java chief architekt himself, Mark Reinhold, stated
„Serialization was a horrible mistake in 1997.“
The question, if the Spring framework may flush objects, was already asked on here:
Does Spring flush objects to disk under load?
So I ask the question:
Do any modern application servers, frameworks or the J2EE implementation itself (especially Java components that interact with CDI, EJB, JPA) flush objects to disk under heavy load?
Or is this statement outdated?
TL;DR
If you're not implementing a distributable web application, you do not enable session persistence, and you only use in-memory caches, you might get away without needing Serializable anywhere.
Explanation
For session replication, Java Serialization is still a must for the latest Servlet Specification: https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0.html#distributed-environments
A common usecase is if you have multiple servers behind a load balancer, and you login on one server, you get a JSESSIONID cookie. If the load balancer sends you to a different server for the next request, your login attributes and other session-scoped attributes will be serialized and replicated on the new server, so your JSESSIONID is still valid there.
Another usecase where you need Serialization for your session-scoped attributes, is when the application server decides to swap sessions to disk. For e.g. Tomcat 8, this can be configured to activate when there are too many sessions to keep in memory, or when the server is restarted, and you want to keep the sessions alive. See
https://tomcat.apache.org/tomcat-9.0-doc/config/manager.html
Every Servlet-5.0 compatible application server must support Serializable objects in Http Sessions by default for these kinds of usecases.
For some servers, this can be tweaked or overridden by using e.g. Jackson-JSON serialization or something similar. See e.g. How to use jackson instead of JdkSerializationRedisSerializer in spring
Another common usecase is caching. This is used to keep objects accessible as fast as possible, ideally in memory, but possibly temporarily offloaded to disk or to an external cache server.
There is a standard API for it (JSR-107) that explicitly chose not to require Serializable objects, but most implementations, still use java Serialization for the offloading part as a default.
You can again tweak these to support other serialization mechanisms, e.g. for ehcache: https://www.ehcache.org/documentation/3.8/serializers-copiers.html
Is it possible to describe some services in .proto files which use the existed DTOs & generate the service classes with gradle?
I'm developing client SDK for some server. The current communication layer based on gRPC but I don't want to expose the implementation details (those ugly gRPC messages classes) to the end user. So the public API represented with POJOs.
The existed solution make some conversions between two types of DTOs with custom converters. And this is quite annoying - copy tones of properties just to beautify the public API. So I'm looking a way to reuse the POJO on gRPC layer. Is it possible?
Protobuf really needs those messages in order to be told what to serialize. So while there are some ways to serialize your own message types (like MethodDescriptor.Marshaller), if you want to use Protobuf you'll need to copy between the different types of objects.
I am using XStream as part of my application for serializing objects. For one of the use cases, I have to serialize some of the objects implementing Externalizable interface. For my use case I would like to serialize them using native Java serialization.
I found a link on the internet, http://old.nabble.com/How-to-remove-Externalizable-Converter-td22747484.html, which helped me address this issue and started using Reflection Converter for Externalizable objects.
When testing the application, I am seeing that the application is spending lot of time (10's of seconds) in converter code during highly concurrent access. I can see that the problem is in the buildMap method of FieldDictionary.
I was wondering if there is a better way to address my original issue? Is the performance for Reflection Converter expected to be bad when having highly concurrent environment?
To give some additional context on the environment. It is a web application and the serialization is happening during the request processing and application can have 100's of concurrent threads.
I really appreciate any help/advice regarding this.
This is technically not an answer.. but I hope it helps anyways.
While creating a Java Swing based desktop app that was used for Bio-molecular research modeling, we were serializing very complicated and interconnected object graphs to disk for performance reasons.
Even after working our way through Externalization and Serializable related issues, we had to abandon the whole approach and start fresh, because Java serialization is very sensitive to object structure / name etc. Which means innocent refactoring of the model was leading to major crashes in production, when users tried to load old serialized models.
Eventually we created a data store friendly object structure (No strong inter-references to other nodes in the graph), and serialized this structure. This was much simpler, less error prone and much faster than serializing and deserializing the original graph. This also meant that we could refactor / modify our domain graph objects at will, as long as the Adapters (components that converted Domain objects to DataStore objects) was kept updated properly.
I have a model (MVC) class whose internal state (which basically contains of private int fields) I want to store.
The program is running on Android (for now) so I need to store the in a Bundle, but I'll be using the same class later in a desktop application where I'll have to store the state some other way, so I can't reference Bundle directly in my class.
So my question is: What is the best way to store (and retrieve) the state of a class without exposing it's implementation?
The best I could think of removing the private access modifier so that the fields become package accessible and create read/write helper classes in the same package, but that somehow seems wrong.
I'm not familiar with the persistence mechanisms on Android, but in general, it's a good idea to separate your persistence logic (i.e. the code that stores objects' state) from the domain objects that actually contain the data. That's the approach taken by JPA and virtually all modern object-relational mapping tools in Java, for example. So yes, referencing Bundle objects directly in your domain classes doesn't sound like the right strategy, especially if you plan to use the same classes in a non-Android environment, too.
My advice is to serialize the object state into XML, which is portable across environments. There are lots of open source tools available that help make this easy and don't require any special code in your domain classes. The two I'm most familiar with are JiBX and Castor. I don't know if either will work on Android, but even if Android has its own tools to transform objects to and from XML, you still might be able to use JiBX or Castor on the desktop side, since they can adapt to many different XML formats.
Once you have the data in XML form, you can persist it using whatever means is most appropriate on the target environment. On the desktop app, that probably means files in the user's home directory. On Android, I guess it would be bundles, but that's not my area of expertise. Good luck!
Take a look at the bridge pattern, as well: http://en.wikipedia.org/wiki/Bridge_pattern
As Rob said, you need to decouple the persistence from the data objects, so you can handle data uniformly and use a bridge to handle the persistence in different platforms.
Currently, I only know a way of doing RPC for POJOs in Java, and is with the very complex EJB/JBoss solution.
Is there any better way of providing a similar functionality with a thiner layer (within or without a Java EE container), using RMI or something that can serialize and send full blown objects over the wire?
I'm not currently interested in HTTP/JSON serialization BTW.
EDIT: For clarification: I'm trying to replace an old EJB 2.1/JBoss 4 solution with something more easy to manage at the container level. I need to have entire control over the database(planning to use iBATIS which would allow me to use fairly complex SQL very easily), but the only things I want to keep over the wire are:
Invocation of lookup/data modification methods (automagic serialization goes here).
Transparent session control (authentication/authorization). I still have to see how to accomplish this.
Both items have to work as a whole, of course. No access should be granted to users without credentials.
Because I'm not very fond of writing webapps, I plan to build a GUI (Swing or SWT) that would only manage POJOs, do some reporting and invoke methods from the container. I want the serialization to be as easy as possible.
As is nearly always the case, Spring comes to the rescue. From the reference documentation, you will want to read Chapter 17. Remoting and web services using Spring.
There are several methods to choose from. The beauty of Spring is that all your interfaces and implementations are vanilla POJOs. The wiring into RMI or whatever is handled by Spring. You can:
Export services using RMI:
probably the simplest approach;
Use HTTP invoker: if remote access is an issue, this might be better for firewalls, etc than pure RMI; or
Use Web Services, in which case I would favour JAX-WS over JAX-RPC.
Spring has the additional benefit in that it can do the wiring for both the server and the client, easily and transparently.
Personally I would choose either (2) or (3). HTTP is network friendly. It's easy to deploy in a Web container. Jetty's long-lived connections give you the option over server push (effectively) over HTTP.
All of these methods allow complex objects to be sent across the wire but they are subtly different in this regard. You need to consider if your server and client are going to be distributed separately and whether it's an issue if you change the interface that you need to redistribute the class files. Or you can use a customized serialization solution (even XML) to avoid this. But that has issues as well.
Using a Web container will allow you to easily plug-in Spring Security, which can be a bit daunting at first just because there are so many options. Also, HttpSession can be used to provide state information between requests.
Simple RPC is exactly what RMI was built for. If you make a serializable interface, you can call methods on one app from another app.
If you only need value objects then just ensure the POJOs implement Serializable and write the objects across sockets (using ObjectOutputStream). On the receiving end read the objects using ObjectInputStream. The receiving end has to have a compatible version of the POJO (see serialVersionUID).
Hessian/Burlap 'protocol-ize this: http://hessian.caucho.com/ and http://www.caucho.com/resin-3.0/protocols/burlap.xtp
You could try XStream (http://x-stream.github.io/) over REST. Easy to apply on e pre-existing set of pojos.
Can you give some further information as to what you're trying to achieve, since you're not interested in rest/json ?