Java - Framework to detect if Object has changed / dirty detection mechanism - java

Dear all I am currently implementing a java client which is using quite heavily third party webservices. In order to gain performance I just like to call webservices only in case the objects on my client side has been modified (become dirty).
Instead of writing an own kind of framework which is able to detect if an object is dirty, exists there any open / generic framework which can be reused and is not bind to its core product (e.g. hibernate)?

I presume with object you don't mean a single scalar value but a bean.
Technically you can do all sorts of fancy stuff to detect the bean mutation, for example changing the byte code and add some code whenever the object field is updated.
Another option is to keep a copy of the old bean instance and compare it.
So actually the problem reduces to comparing two beans, which was asked here: how to generically compare entire java beans? Probably you find more, there are a lot of frameworks dealing with beans in general.
However, since you call webservices, you must have a mechanism to serialize your objects. You could use the serialized form of the old and new object to compare for identity before sending the update request.
Change notification: I don't recommend attaching change listeners to every bean. This might change your general performance and introduce memory leaks. There is also a transaction problem: If more then one bean property is updated, when is the update of a bean completed? So you need an explicit call after the mutation anyways.
Note to myself and other caching guys: Actually this is the use case to provide a method like Cache.putIfNotEquals(key, value) on a cache, which is not much efford. The cache stores the previous value already and it does only call the cache writer (in a write through setup) if the value changed.

To give others a starting point how this can look like.
TestBean bean1 = new TestBean("AAA");
TestBean bean2 = new TestBean("BBB");
log.info("serialize...");
ByteArrayOutputStream str1 = new ByteArrayOutputStream();
ObjectOutputStream oos1 = new ObjectOutputStream(str1);
oos1.writeObject(bean1);
byte[] serialized1 = str1.toByteArray();
oos1.close();
ByteArrayOutputStream str2 = new ByteArrayOutputStream();
ObjectOutputStream oos2 = new ObjectOutputStream(str2);
oos2.writeObject(bean2);
byte[] serialized2 = str2.toByteArray();
oos2.close();
log.info("compare");
boolean same = Arrays.equals(serialized1, serialized2);
The advantage of this approach
you serialize the whole object structure so it supports complex hierarchies out of the box and you do not have to care about cycles (parent / childs)
you can use "transient" key word on members which you like to exclude from the serialization / comparison
you have not to add some boiler plate code to your bean classes (apart that the class needs to implement the Serializable interface)
disadvantages
it is not fine grained, so you don't get out of the box which fields are dirty. There are sophisticated approaches by using an own serialization format
I did not yet had a thought about performance but I could imagine that other approaches comes also not for free, so here you need to test and tune the approach your self.

Related

How to get XStream to map old deleted field to a new one of a different type?

We've made changes to our objectmodel and hence XML, such that some boolean fields are no longer used and superseded by enums.
For example say the object had
#XStreamAlias("showABC")
private boolean showABC;
and that's now superseded by
#XStreamAlias("showOption")
private ShowOptions showOption;
I'd like to remove the defunct booleans but need to be able to read old XML that still contains them as the new field needs to be initialised base on the value of the old..
Currently we just leave the old fields behind and mark them #Deprecated so they can still be read and have readResolve() do the initialisation e.g.
if (showABC == false) {
showOption = ShowOptions.NONE;
}
Leaving these fields around is ugly as hell though, polluting the XML!
Is there a way to delete the fields and create a converter to do the right thing? I don't want to create a converter that manually reads all the fields as there's LOTS of them.
Currently leaning towards another ugly approach of extending AbstractReflectionConverter and munging about in doUnmarshal() so I can have handleUnknownField() do something more useful..
But is there a better solution? Perhaps through the use of Mappers although I can't find any details in the docs/tuts, just right to the source.
UPDATE
Whilst looking at the use of Mappers in AbstractReflectionConverter I thought I might get lucky by making the old field an alias of the new and having a converter that can deal with the boolean and the enum:
xstream.aliasField("showABC", MyModel.class, "showOption");
xstream.registerLocalConverter(MyModel.class, "ShowOptions", new ShowConverter());
But wouldn't you know, this throws a DuplicateFieldException so this approach would need munging to allow overwriting (as of course we've got intermediate XML with both the old and new in it o_O); fortunately new fields are declared after the old so ordering is ok..
I'd have thought this kind of conversion requirement isn't uncommon?!

Use of Serializable other than Writing& Reading object to/from File

In Which Cases it is a good coding practice to use implements serializable other than Writing & Reading object to/from file.In a project i went through code. A class using implements serializable even if in that class/project no any Writing/Reading objects to/from file?
If the object leaves the JVM it was created in, the class should implement Serializable.
Serialization is a method by which an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
This is the main purpose of de-serialization. To get the object information, object type, variable type information from a written(loosely speaking) representation of an object. And hence serialization is required in the first place, to make this possible.
So, whenever, your object has a possibility of leaving the JVM, the program is being executed in, you should make the class, implement Serializable.
Reading/Writing objects into files (Memory), or passing an object over internet or any other type of connection. Whenever the object, leaves the JVM it was created in, it should implement Serializable, so that it can be serialized and deserialized for recognition once it enters back into another/same JVM.
Many good reads at :
1: Why Java needs Serializable interface?
2: What is the purpose of Serialization in Java?
Benefits of serialization:
To persist data for future use.
To send data to a remote computer using client/server Java technologies like RMI , socket programming etc.
To flatten an object into array of bytes in memory.
To send objects between the servers in a cluster.
To exchange data between applets and servlets.
To store user session in Web applications
To activate/passivate enterprise java beans.
You can refer to this article for more details.
If you ever expect your object to be used as data in a RMI setting, they should be serializable, as RMI either needs objects Serializable (if they are to be serialized and sent to the remote side) or to be a UnicastRemoteObject if you need a remote reference.
In earlier versions of java (before java 5) marker interfaces were good way to declare meta data but currently we having annotation which are more powerful to declare meta data for classes.
Annotation provides the very flexible and dynamic capability and we can provide the configuration for annotation meta deta that either we want to send that information in byte code or at run time.
Here If you are not willing to read & write object then there is one purpose left of serialization is, declare metadata for class and if you are goint to declare meta data for class then personally I suggest you don't use serialization just go for annotation.
Annotation is better choice than marker interface and JUnit is a perfect example of using Annotation e.g. #Test for specifying a Test Class. Same can also be achieved by using Test marker interface.
There is one more example which indicate that Annotations are better choice #ThreadSafe looks lot better than implementing ThraedSafe marker interface.
There are other cases in which you want to send an object by value instead of by reference:
Sending objects over the network.
Can't really send objects by reference here.
Multithreading, particularly in Android
Android uses Serializable/Parcelable to send information between Activities. It has something to do with memory mapping and multithreading. I don't really understand this though.
Along with Martin C's answer I want to add that - if you use Serializable then you can easily load your Object graph to memory. For example you have a Student class which have a Deportment. So if you serialize your Student then the Department also be saved. Moreover it also allow you -
1. to rename variables in a serialized class while maintaining backwards-compatibility.
2. to access data from deleted fields in a new version (in other words, change the internal representation of your data while maintaining backwards-compatibility).
Some frameworks/environments might depend upon data objects being serializable. For example in J2EE, the HttpSession attributes must be serializable in order to benefit from Session Persistence. Also RMI and other dark ages artifacts use serialization.
Therefore, though you might not immediately need your data objects to be serializable, it might make sense to declare Serializable just in case (It is almost free, unless you need to go through the pain of declaring readObject/writeObject methods)

what is the best way to merge two java beans in RESTful API?

The scenario is simple:
UI call RESTful API to get an object tree, then UI change some data and call RESTful API to update it.
But for security or performance reason..., my RESTful API can NOT bring the whole object tree to the UI.
We have two choose for this purpose: creating an individual Java Bean for RESTful API or extend existing business Java Bean plus #JsonIgnore.
The second looks smarter because we re-use business class.
But Now we have a trouble: I need to merge the object from UI with the object from DB, otherwise I will lose some data.
But how do I know which piece of data will come from UI?
I know I can hard code to copy fields one by one.
But this way is dangerous.
I am asking for generic way to avoid hard code to copy fields.
I tried org.apache.commons.beanutils.BeanUtils, but it can't meet the requirement because it always overwrite target fields.
So I am thinking this way:
If the field in UI bean is not Null, then overwrite the value of the same name field in destination bean. but how do I handle if the field is some kind of primitive type like int which have default value 0?
I don't know if the field really carry an UI value 0 or just not comes back from UI.
I tried to convert primitive type to object type, but it still have troubles on boolean type, many java tools don’t support “ Boolean isValid(){…}” like BeanUtils. And this kind converting is dangerous on existing code.
I tried those code:
JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClass.construct(MyClassDTO.class, ai, null);
String[] ignoredList = ai.findPropertiesToIgnore(ac);
for(String one: ignoredList){
System.out.println(one);
}
but ignoredList is always null. I am using Jackson 1.9.2
You could consider using JsonPatch. We use it and it works quite well. Of course it means you apply patches at the JSON level and not in the bean directly so if you need to support more than just JSON, it might be a problem.
Here's an implementation: https://github.com/fge/json-patch
I found the solution on Jackson:
MyBean defaults = objectMapper.readValue(defaultJson, MyBean.class);
ObjectReader updater = objectMapper.readerForUpdating(defaults);
MyBean merged = updater.readValue(overridesJson);
it comes from :
readerForUpdating
merging on Jackson

When to use Spring prototype scope?

I want to know when should I exactly use the prototype scope in Spring? I have understood that singleton returns the same object instance if the bean is requested for.
Then why should we consider prototype?
Explanations with examples would help a lot to understand the need for it.
To be clear simple definitions:
Prototype scope = A new object is created each time it is injected/looked up. It will use new SomeBean() each time.
Singleton scope = The same object is returned each time it is injected/looked up. Here it will instantiate one instance of SomeBean and then return it each time.
Prototype bean is created at the time of usage. So when you would like to have stateful beans there is a strong need sometimes to have prototypes scope or when you don't want to cache any values in beans. Prototype bean can be associated with one session or some call.
Example:
A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state; it was just easier for this author to reuse the core of the singleton diagram.
There are some interesting use cases by using scope prototype you will build a better and reliable application design/architecture, for example, a real-time system.
Imagine that you must build a real-time system for vehicle tracking, and you will have 2.000.000 cars sharing information every 5 seconds,
In the server side, you will work with two or more distinct group of configurations, one for Cars and another one for Trucks.
Based on this simple example, if you design your application to work with distinct configuration groups in memory through the prototype pattern you will achieve a better performance.
So, in this case, whenever the server receives a new message from a Truck, for example, the server will get the instance of the configuration in memory from a hashmap of instances of VehicleGrupConfiguration and then apply the configuration behavior that this message must have, e.g: like time-out, retry... and etc.
I would like to highlight that there are many ways to implement this situation, but this example shows that a prototype pattern is very powerful in matters of performance and design patterns.
As the documentation says, creating a bean Foo with prototype scope is same as calling:
Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);
The only good reason to use a prototype scope bean instead of new that is when the dependencies used for creation and initialization of the instance should be kept outside the code that needs a new instance.
As an example:
// need to explicitly mention dependencies here
public void createdWithNew(Dependency dependency1, Dependency dependency2) {
Foo foo = new Foo(dependency1, dependency2, ...);
foo.doSomething();
}
// Dependencies managed in class Foo by Spring
public void createdWithSpring(Foo foo) {
foo.doSomething();
}
An example is if you wanted to write persistence code similar to EJB2 Java Entity beans, such as
Person p = ...
p.setName("John Doe");
p.save(); // write to DB
Instead of using the JPA way
Person p = new Person();
p.setName("John Doe");
personService.save(p); // write to DB
In the entity bean code style, the person instance needs to know how it should be persisted, so it needs to be injected with persistence details that the code writing a person should not be aware about.
Another example:
If you want to use the non-threadsafe SimpleDateFormat Java class in many places of your application, with a format pattern from a configuration file(maybe using different formats depending on other conditions). Instead of creating a new format instance in all those places loading also the formatting string from a file (or spring property), you could use the prototype scope to get a fresh instance every time, with the details of setting the common format being in one place.

Implementing my own serialization in java

How can I implement serialization on my own. Meaning I don't want my class to implement serializable. But I want to implement serialization myself. So that without implementing serializable I can transfer objects over network or write them to a file and later retrieve them in same state. I want to do it since I want to learn and explore things.
Serialization is the process of translating the structure of an object into another format that could be easily transfered across network or could be stored in a file. Java serializes objects into a binary format. This is not necessary if bandwidth/disk-space is not a problem. You can simply encode your objects as XML:
// Code is for illustration purpose only, I haven't compiled it!!!
public class Person {
private String name;
private int age;
// ...
public String serializeToXml() {
StringBuilder xml = new StringBuilder();
xml.append("<person>");
xml.append("<attribute name=\"age\" type=\"int\">").append(age);
xml.append("</attribute>");
xml.append("<attribute name=\"name\" type=\"string\">").append(name);
xml.append("</attribute>");
xml.append("</person>");
return xml.toString();
}
Now you can get an object's XML representation and "serialize" it to a file or a network connection. A program written in any language that can parse XML can "deserialize" this object into its own data structure.
If you need a more compact representation, you can think of binary encoding:
// A naive binary serializer.
public byte[] serializeToBytes() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
// Object name and number of attributes.
// Write the 4 byte length of the string and the string itself to
// the ByteArrayOutputStream.
writeString("Person", bytes);
bytes.write(2); // number of attributes;
// Serialize age
writeString("age", bytes);
bytes.write(1); // type = 1 (i.e, int)
writeString(Integer.toString(age), bytes);
// serialize name
writeString("name", bytes);
bytes.write(2); // type = 2 (i.e, string)
writeString(name, bytes);
return bytes.toByteArray();
}
private static void writeString(String s, ByteArrayOutputStream bytes) {
bytes.write(s.length());
bytes.write(s.toBytes());
}
To learn about a more compact binary serialization scheme, see the Java implementation of Google Protocol Buffers.
You can use Externalizable and implement your own serialization mechanism. One of the difficult aspects of serialization is versioning so this can be a challenging exercise to implement. You can also look at protobuf and Avro as binary serialization formats.
You start with reflection. Get the object's class and declared fields of its class and all superclasses. Then obtain value of each field and write it to dump.
When deserializing, just reverse the process: get class name from your serialized form, instantiate an object and set its fields accordingly to the dump.
That's the simplistic approach if you just want to learn. There's many issues that can come up if you want to do it "for real":
Versioning. What if one end of the application is running new version, but the other end has an older class definition with some fields missing or renamed?
Overwriting default behavior. What if some object is more complex and cannot be recreated on a simple field-by-field basis?
Recreating dependencies between objects, including cyclic ones.
... and probably many more.
Get the Java Source code and understand how Serialization is implemented. I did this some month ago, and now have a Serialization that uses only 16% of the space and 20% of the time of "normal" serialization, at the cost of assuming that the classes that wrote the serialized data have not changed. I use this for client-server serialization where I can use this assumption.
As a supplement to #Konrad Garus' answer. There is one issue that is a show-stopper for a full reimplementation of Java serialization.
When you deserialize an object, you need to use one of the object's class's constructors to recreate an instance. But which constructor should you use? If there is a no-args constructor, you could conceivably use that. However, the no-args constructor (or indeed any constructor) might do something with the object in addition to creating it. For example, it might send a notification to something else that a new instance has been created ... passing the instance that isn't yet completely deserialized.
In fact, it is really difficult replicate what standard Java deserialization code does. What it does is this:
It determines the class to be created.
Create an instance of the class without calling any of its constructors.
It uses reflection to fill in the instance's fields, including private fields, with objects and values reconstructed from the serialization.
The problem is that step 2. involves some "black magic" that a normal Java class is not permitted to do.
(If you want to understand the gory details, read the serialization spec and take a look at the implementation in the OpenJDK codebase.)

Categories