Here's my situation:
I have a server application, providing a remote interface which uses bean objects as call parameters / return values. These are of course Serializable. For instance, a Doctor, that works in a Surgery.
For my local application, i have extended these call objects: For instance, the doctor has an additional password field so the doctor's password can be stored locally. Now my local objects are also Serializable, and i also use this to send these around through the local network.
What is the easiest way for me now, to use objects of my extended implementations in a remote call to the server? The server obviously can't reconstruct my serialized implementations, because he doesn't know my specialized classes.
Do i have to manually create a un-extended bean object from my extended one by basically copying all the fields except the new ones? or is there a better/easier way to do this? Overwriting the serialization methods is not an option because, as i stated above, i still need my local objects to be normally Serializable too.
The server obviously can't reconstruct
my serialized implementations, because
he doesn't know my specialized
classes.
Unless your server can get to know about your specialized classes via a jar in the classpath, you won't be able to have it unserialize your classes.
Creating proxies could be an angle to explore, but with no guarantee this would work (not enough details about your specific situation).
An easier solution is to use a root class for your beans, containing or extending a hash map and store the properties/values in it. Instead of creating getter and setter for each property, implement only one pair and provide the property name as a string.
The server won't have any issue to unserialize it, unless one of the Serializable object in the map is unknown to the server. This method allows you to add any extra bean information in it and the server will always know how to deal with it.
There is also a trickier angle you could try. The class Class is serializable by itself. Therefore, if you transferred it before you transfer your beans, may be the server could learn about it first. I have never tried this myself, so I don't know if it would work. Just an idea.
Related
[Context]
I need to send data from one applet to another. In addition, one of the applets needs to be deleted and reinstalled. After the installation, data exchange between the applets needs to be possible.
Is Shareable Interface useful to realize that?
[Theoretical]
In general, I would like to know the cases where shareable interface is a good idea and What its principal use.
[Practice]
I took example from this answer but it does not work. I think I did not understand how to implement. I tried to create two applets in the same package, one master and one slave. But I got 6F 00 when slave is selected. I did other test with two packages. But I got same error.
Shareable allows you to exchange the data between applets on the card.
There are some limitations though, the main being the fact that one cannot freely exchange internal objects. Only objects allowed for sharing can pass via the Shared interface. The example you mention uses some proprietary “SharedArray” interface to implement this.
By default, only standard global objects such as APDU backing array, or various STK objects can be used for this purpose.
In addition, it is possible to pass simple value types such as byte and short via the Shared interface methods.
In some cases, especially in STK environments the Shared interface is used to initiate the operations while the data is passed via a separate EF on the card which is used as a “mailslot”.
Regarding, the implementation itself, one needs to remember that Shareable interface is just a marker and as such you need to define a concrete interface that inherits from Shareable to be able to use it in the application.
The above interface constitutes a hard dependency for any application using or implementing this interface.
As a result, the package containing the interface definition cannot be deleted if any of the other applets/libraries use it.
One of the common options is to define the interface in a separate library and install it first. Since it is not likely to change, and if it does you would change the AID,version anyway, all other clients can be freely installed and deleted.
Lastly, please keep in mind Sharable interface should be used with care due to security issues associate with data sharing.
I highly recommend getting a copy of “Java Card Technology for Smart Cards: Architecture and Programmer's Guide” which covers these topics and much more.
Answering your question in order
[Context]
Shareable interface is used when one applet(Client Applet) need to access methods from another applet(Server applet) provided both the applets are located in different packages.Applets in different packages are separated by a firewall to prevent access to applet data across package.
Applet instances can be deleted in any order but Applet package should deleted in order. That is, first client package is deleted than server package is deleted.
[Theoretical]
Shareable interface is useful for object sharing since firewall restrict object sharing between packages.
For proper uses cases kindly go through this white paper - www.usenix.org/legacy/event/smartcard99/full_papers/montgomery/montgomery.pdf
[Practice]
Kindly check solution for shareable interface implementation - https://stackoverflow.com/a/57200926/4752262
Someone thought it would be a good idea to store Objects in the database in a blob column using Java's default serialization methods.
The structure of these objects is controlled by another group and they changed a field type from BigDecimal to a Long,
but the data in our database remains the same.
Now we can't read the objects back because it causes ClassCastExceptions.
I tried to override it by writing my own readObject method,
but that throws a StreamCorruptedException because what was written by the default writeObject method.
How do I make my readObject call behave like Java's default one?
Is there a certain number of bytes I can skip to get to my data?
Externalizable allows you to take full control of serialization/deserialization. But it means you're responsible for writing and reading every field,
When it gets difficult though is when something was written out using the default serialization and you want to read it via Externalizable. (Or rather, it's impossible. If you try to read an object serialized with the default method using Externalizable, it'll just throw an exception.)
If you've got absolutely no control on the output, your only option is to keep two versions of the class: use the default deserialization of the old version, then convert to the new. The upside of this solution is that it keeps the "dirty" code in one place, separate from your nice and clean objects.
Again, unless you want to do things really complicated, your best option is to keep the old class as the "transport" bean and rename the class your code really uses to something else.
If you want to read what's already in your database your only option is to get them to change the class back again, and to institute some awareness that you're relying on the class definition as it was when the class was serialized. Merely implementing your own readObject() call can't fix this, and if the class is under someone else's control you can't do that anyway.
If you're prepared to throw away the existing data you have many other choices starting with custom Serialization, writeReplace()/readResolve(), Externalizable, ... or a different mechanism such as XML.
But if you're going to have third parties changing things whenever they feel like it you're always going to have problems of one kind or another.
BigDecimal to Long sounds like a retrograde step anyway.
Implement the readObject and readObjectNoData methods in you class.
Read the appropriate type using ObjectInoutStream.readObject and convert it to the new type
See the Serializable interface API for details.
More Details
You can only fix this easily if you control the source of the class that was serialized into the blob.
If you do not control this class,
then you have only a few limited and difficult options:
Have the controlling party give you a version of the class that reads the old format and writes the new format.
Write you own form of serialization (as in you read the blob and convert the bytes to classes) that can read the old format and generate new versions of the classes.
Write you own version of the class in question (remove the other from the class path) which reads the old format and produces some intermediate form (perhaps JSON).
Next you have to do one of these
Convince the powers that be that the blob technique is shitty and should be done away with. use the current class change as evidance. Almost any technique is better that this. Writing JSON to the db in the blob is better.
Stop depending on shitty classes from other people. (shitty is a judgement which I can only suspect, not know, is true). Instead create a suite of classes that represent the data in the database and convert from the externally controlled classes to the new data classes before writing to the database.
I'm using an API providing access to a special server environment. This API has a wide range of Data objects you can retrieve from it. For Example APICar
Now I'd like to have "my own" data object (MyCar) containing all information of that data object but i'd like to either leave out some properties, augment it, or simply rename some of them.
This is because i need those data objects in a JSON driven client application. So when someone changes the API mentioned above and changes names of properties my client application will break immediatly.
My question is:
Is there a best practice or a design pattern to copy objects like this? Like when you have one Object and want to transfer it into another object of another class? I've seen something like that in eclipse called "AdapterFactory" and was wondering if it's wide used thing.
To make it more clear: I have ObjectA and i need ObjectB. ObjectA comes from the API and its class can change frequently. I need a method or an Object or a Class somewhere which is capable of turning an ObjectA into ObjectB.
I think you are looking for Design Pattern Adapter
It's really just wrapping an instance of class A in an instance of class B, to provide a different way of using it / different type.
"I think" because you mention copying issues, so it may not be as much a class/type thing as a persistence / transmission thing.
Depending on your situation you may also be interested in dynamic proxying, but that's a Java feature.
What are the key points in checklist to be checked while implementing good serialization in java (I'm not really looking for , implements Serializable, write, readObject etc).
Instead , How to reduce the size of the object , Probably how to make the object in zip format and send over the network etc..
How to ensure the secure mode of transfer.
any others like this..
How to reduce the size of the object: new ObjectOutputStream(new GZipOutputStream(new BufferedOutputStream(out)). But this is a space-time tradeoff. You may find that it makes performance worse by adding latency.
How to ensure the secure mode of transfer: SSLSocket or an HTTPS URL.
Any others like this
Any others like what? You will need to be specific.
Do not use serialization to "persist" objects - this makes schema management (i.e. changing what constitutes a class's state) almost unworkable
Always declare a serialVersionUID field; otherwise you will not be able to add methods, or change the class in any way (even non-state-changing ones) without old versions of your code being unable to deserialize the objects (an IncompatibleClassVersionError will be thrown)
try and override readResolve if you are deserializing a logical "enum" instance of a class (typesafe enumeration pattern)
Make sure you are 100% happy with the name of the variables which make up the state of your class. Once you have serialized instances around, you cannot change the variable names
Do not implement Serializable unless you really have to
Do not make your interfaces Serializable - the implementation classes may be, but the interfaces should not be
Do not make serialization part of the way your library passes objects around, unless you are the only producer and consumer of the objects (e.g. server-GUI communication). Use a binary/wire protocol instead (e.g. protobuf)
To minimize what is sent over the wire, you could use swizzling. That is, perhaps you have a Product class; the serialized form might just be a unique int id field. All other methods could then be made to construct relevant state as required (perhaps as a database call, or call to some central service)
Make sure, if you are serializing out an object which contains some collection of elements as part of its state, that you synchronize on the collection. Otherwise you may find that someone modifies the collection as it is being serialized out, resulting in a ConcurrentModificationException
Probably how to make the object in zip format and send over the network etc..
Check out how the game developers for network games implement networking. They know, how to transmit data quickly. Have a look at e.g. http://code.google.com/p/kryonet/
How to ensure the secure mode of transfer. any others like this..
There are a lot of interpretations of secure mode. If you need reliability, use TCP otherwise UDP. If you need encryption use TLS otherwise rot13 may fit. If you need to ensure integrity, append a hash of the values to the message.
How to reduce the size of the object ,
Analyse your data and strip down the objects, so that you only have the necessary data in there. This is very context specific, as the best optimisation can be in the domain. E.g. you can check, if it is possible to send only deltas of the change.
It is an interesting question, but you have to be more specific about your goal or domain to get an answer that fits best.
I have a simple RMI 'compute' server application (similar to this) that accepts objects of some interface type from clients over RMI, executes the compute() method of the received object and returns the result over RMI to the remote client. The jobs are 'one-offs' and there is no interaction between the different jobs or between objects of different jobs.
I would like to be able to modify classes and submit instances to the compute server for execution without constantly restarting the server JVM. However when a class that has been modified is submitted again as a parameter to a remote call it's method behaviour does not change (this occurs with anonymous classes also). I have been reading up about serialization and I realise that this is to do with the ClassLoader being unable to modify existing classes.
From my reading on SO and elsewhere I realise that somehow the ClassLoader that loaded the stream class must be GC'd and replaced in order to load a new version of my class. I have an idea how to do this but the situation seems complicated by the underlying RMI runtime and it having its own RMIClassloader.
My question is: What would be the easiest way to load each new version of a class received via RMI parameters. Ideally I'm looking for a way to have each remote call get a new ClassLoader and to dispose of it upon return. Is this feasible to do without an intricate knowledge of customised ClassLoaders and the internals of RMI?
Any pointers to reading materials or examples welcome!
Edit: here is the compute server's remote interface:
public interface ComputationEngine extends Remote {
public Object execute(Task t) throws RemoteException;
}
and the 'compute job' interface, Task:
public interface Task extends java.io.Serializable {
public Object compute();
}
The only way to this is to have a new ClassLoader when you want to change a Class.
How about making use of the URLClassLoader and making the code available from a URL
I use it in one of my projects to update APIs when the jar file changes. Take a look here:
http://code.google.com/p/open-forum/source/browse/trunk/Wiki/org/one/stone/soup/wiki/jar/manager/JarManager.java
Line 184+
Check your emails :-)
This isn't really answering your question, but it might be possible to make changing part of your classes into data instead of the actual class. Use a Map instead of fields, etc. You'd have a lot fewer classes floating around, and your code would probably be simpler too.