I have a class / object that uses a listener interface. As far as I understand, those can't be serialized, at least I get an NotSerializableException when trying to.
Can I detect from within the object when I's gettings serialized (some form of callback) so I can remove the listener from the object?
I know I can set the listener to null from outside of the object, but it would be easier the way I described.
Don't do this. make your class implement Parcelable and provide the serialization methods yourself. Then you can decide which members get serialized and how that is done.
Related
I want a method that returns an object that is heavy to istantiate like an ObjectMapper, and since it's heavy to istantiate every time an object with new settings is made this value is cached away in a map, the object is meant to be shared among multiple threads so I don't want it to be modified from outside since this can lead to obvious problems.
I could wrap it inside another class and not give access to the methods that modify the settings, but the code would be very long. Is there any simple way to do this?
ObjectMapper here is just an example of the use case, could be a generic object.
I'm kind of new to Java and have a rather simple question:
I have an interface, with a method:
public interface Interface_Updatable {
public void updateViewModel();
}
I implement this interface in several classes. Each class then of course has that method updateViewModel.
Edit: I instantiate these classes in a main function. Here I need code that calls updateViewModel for all objects that implement the interface.
Is there an easy way to do it combined? I don't want to call every method from every object instance separately and keep that updated. Keeping it updated might lead to errors in the long run.
The short form is: no, there's no simple way to "call this method on all instances of classes that implement this interface".
At least not in a way that's sane and maintainable.
So what should you do instead?
In reality you almost never want to just "call it on all instances", but you have some kind of relation between the thing that should trigger the update and the instances for which it should be triggered.
For example, the naming of the method suggests that instances of Interface_Updatable are related to the view model. So if they "care" about changes to the view model, they could register themselves as interested parties by doing something like theViewModel.registerForUpdates(this), the view model could hold on to a list of all objects that registered like this and then loop over all the instances and calls updateViewModel on each one (of course one would need to make sure that unregistration also happens, where appropriate).
This is the classical listener pattern at work.
But the high-level answer is: you almost never want to call something on "all instances", instead the instances you want to call it on have some relation to each other and you would need to make that relation explicit (via some registration mechanism like the one described above).
There is no easy way to call this method on all classes that implement this interface. The problem is that you need to somehow keep track of all the classes that implement this interface.
A possible object-oriented way to do this would be passing a list containing objects that are instances of classes that implement the Interface_Updateable interface to a function, and then calling updateViewModel on each object in that list:
public void updateViewModels(List<Interface_Updateable> instances) {
for(var instance : instances) {
instance.updateViewModel();
}
}
I am writing an android application and I need to have two classes use the same KeyguardLock object but I am experiencing extreme difficulty in sharing (via serialization) that object. I have tried using the serialization stackoverflow example link but that didn't work at all. I get a "not serializable" IO exception trying to save the object. I have also tried using JSONObject.
Any ideas? Has anyone run into a similar problem?
Why are you trying to serialize it? A object can only be serialize if it implements Serializable which KeyguardLock doesn't.
If you're trying to pass it around Activities, either create a custom Application object and store it there. Or use a public static variable in a class and access it via that. The static variable is probably the better option for this.
We have an annoying log message coming from Weblogic whenever we invalidate the HTTPSession when it has objects that are not serializable (which we don't care about but which is polluting our logs). Tweaking our log4j configuration to not log this message does not appear to be an option (the message is coming from a generic Weblogic class and we dont want to supress all messages from this class and other than writing our own adapter to look at messages about to be written to the log and suppressing the deserialization error messages I dont know how we would do it through log4j configuration).
In order to temporarily fix this to clean up our logs I want to intercept calls to add objects to the HTTP Session so that the class of the object being added (and any objects in its object graph) have their instance variable declarations changed to transient. Figured I would intercept calls by adding an HTTPSesssionEventListener and then modifying the Class's instances variables using the reflection libraries.
Does anyone know if this would work?
Does anyone have a better suggestion and/or know if this will/will not work like I would want it to?
Yes. Build to spec!
In compliance with the Java Servlet specification:
The distributed servlet container must throw an IllegalArgumentException
for objects where the container cannot support the mechanism necessary for
migration of the session storing them.
So if you want to avoid this message (and write good portable and distributable code), just make the object you put in HttpSession implement the Serializable interface.
Seriously, I can't believe you are thinking to a solution to workaround the real problem instead of fixing it.
One option if would be
tail -f yourlog | grep -v "annoying line here" > cleanLogFile
Which is much less intrusive. But creates a second file.
I did this for a project where I needed to trace an specific problem and all those stupid messages where getting in the middle.
Why go to that trouble? It sounds just as easy to mark them all as Serializable, as long as all the objects in question are yours.
If that's not possible, .aAnother way is to have a class registered within your webApp that implements HttpSessionAttributeListener. In the attributeAdded method print the sessionID and then serialize the session data:
public void attributeAdded(HttpSessionBindingEvent hsbe)
{
// Handle the details yourself here.
ObjectOutputStream.writeObject(hsbe.getValue())
}
Try modifying the ObjectOutputStream, not the serialized object.
If you extend ObjectOutputStream, you can override the replaceObject method and clear the non-serializable fields or re-create the object without the non-serializable properties.
Another option is to use reflection to nullify the non-serializable fields of the session objects, but that is very risky as a session object could be loaded back and appear to work but then throw a NullPointerException hours or even months later (when the field you nullified is eventually referenced.)
Modifying the classes will probably not work.
It is possible to extend ClassLoader and tweak flags on instance fields but:
If it's your class that contains the non-serializable field then it's simpler to change the code yourself to make it transient
If it's not your class then it will be loaded by a different ClassLoader from your application classes so by the time you see the object it will be too late (because the class has already been loaded.)
You cannot set the transient flag on an individual object, only on a class.
I'm looking for something similar to the Proxy pattern or the Dynamic Proxy Classes, only that I don't want to intercept method calls before they are invoked on the real object, but rather I'd like to intercept properties that are being changed. I'd like the proxy to be able to represent multiple objects with different sets of properties. Something like the Proxy class in Action Script 3 would be fine.
Here's what I want to achieve in general:
I have a thread running with an object that manages a list of values (numbers, strings, objects) which were handed over by other threads in the program, so the class can take care of creating regular persistent snapshots on disk for the purpose of checkpointing the application. This persistor object manages a "dirty" flag that signifies whether the list of values has changed since the last checkpoint and needs to lock the list while it's busy writing it to disk.
The persistor and the other components identify a particular item via a common name, so that when recovering from a crash, the other components can first check if the persistor has their latest copy saved and continue working where they left off.
During normal operation, in order to work with the objects they handed over to the persistor, I want them to receive a reference to a proxy object that looks as if it were the original one, but whenever they change some value on it, the persistor notices and acts accordingly, for example by marking the item or the list as dirty before actually setting the real value.
Edit: Alternatively, are there generic setters (like in PHP 5) in Java, that is, a method that gets called if a property doesn't exist? Or is there a type of object that I can add properties to at runtime?
If with "properties" you mean JavaBean properties, i.e. represented bay a getter and/or a setter method, then you can use a dynamic proxy to intercept the set method.
If you mean instance variables, then no can do - not on the Java level. Perhaps something could be done by manipulations on the byte code level though.
Actually, the easiest way to do it is probably by using AspectJ and defining a set() pointcut (which will intercept the field access on the byte code level).
The design pattern you are looking for is: Differential Execution. I do believe.
How does differential execution work?
Is a question I answered that deals with this.
However, may I suggest that you use a callback instead? You will have to read about this, but the general idea is that you can implement interfaces (often called listeners) that active upon "something interesting" happening. Such as having a data structure be changed.
Obligitory links:
Wiki Differential execution
Wiki Callback
Alright, here is the answer as I see it. Differential Execution is O(N) time. This is really reasonable, but if that doesn't work for ya Callbacks will. Callbacks basically work by passing a method by parameter to your class that is changing the array. This method will take the value changed and the location of the item, pass it back by parameter to the "storage class" and change the value approipriately. So, yes, you have to back each change with a method call.
I realize now this is not what you want. What it appears that you want is a way that you can supply some kind of listener on each variable in an array that would be called when that item is changed. The listener would then change the corresponding array in your "backup" to refect this change.
Natively I can't think of a way to do this. You can, of course, create your own listeners and events, using an interface. This is basically the same idea as the callbacks, though nicer to look at.
Then there is reflection... Java has reflection, and I am positive you can write something using it to do this. However, reflection is notoriously slow. Not to mention a pain to code (in my opinion).
Hope that helps...
I don't want to intercept method calls before they are invoked on the real object, but
rather I'd like to intercept properties that are being changed
So in fact, the objects you want to monitor are no convenient beans but a resurgence of C structs. The only way that comes to my mind to do that is with the Field Access call in JVMTI.
I wanted to do the same thing myself. My solution was to use dynamic proxy wrappers using Javassist. I would generate a class that implements the same interface as the class of my target object, wrap my proxy class around original class, and delegate all method calls on proxy to the original, except setters which would also fire the PropertyChangeEvent.
Anyway I posted the full explanation and the code on my blog here:
http://clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html