GWT: finalize object and remove its event handlers - java

In GWT I have class MyClass that registers some event handlers. There is an object (object1) of MyClass that, at a specific moment, I want to finalize and make its handlers stop listening, because after that I am going to create a different MyClass object (object2).
How can I do that? I already tried with object1 = null, but its handerls keep listening (at least for a while).

The handlers might still exist because the gc didn't get around destroying them.
If it is important that the listeners don't continue to exist then they need to be deregistered.
One way to do this is by deregistering the HandlerRegistration. For example a addClickHandler returns a HandlerRegistration which can be deregistered. When and how to do this depends on your GUI classes. You could put the deregistration in your finalize method but you will probably find that these methods are called very sporadically because of the gc and of course because this is not java but javaScript. So concider putting them in a detach or destroy method of your gui element onDetach or onUnload.

Related

GWT - MVP Event bus. Multiple handlers getting created

I am working in a large application I inherited, and am running into some best practices issues.
Every time a user navigates to our Customer Edit page, a new presenter is created, and a view is set. There is a main presenter for the customer edit, and a main view. There are also sub views within the main view that are used by sub presenters of the main presenter. Within the sub presenters I register event handlers on the event bus.
The issue I'm having is that when a navigates to the contact editor a second time, the presenter is created again, and those events are registered again. Now when an event occurs, it is handled twice, once for each presenter instance.
The presenter isn't held onto by a variable, but the sub view is referenced by the main view. Could It be that this reference in the view is keeping the event handlers from being removed? I was under the impression that event handlers will be removed if that object was garbage collected. If this is not the case, should I be un-registering these event handlers from the event bus?
Update:
The presenters are not being garbage collected.
If I can modify the code to remove all references to those presenters when they are no longer needed, will they be collected, and therefore will the event handlers be removed?
The ResettableEventBus is specifically designed for this - instead of giving the Presenter a global event bus, you wrap up that event bus in the Resettable version. Then, when that presenter is shut down, whoever gave it that event bus resets it, thus cleaning up all handlers that it may have added.
This is how Activities in GWT's Activity/Place framework are managed to prevent them from leaking.
Another option - give each Presenter a method like 'stop()' or 'release()', indicating that it is top to go, and it should mop up after itself - cancel in-progress RPC calls, remove dialog boxes, cancel event handlers. And as above, the Activity api has a method to indicate that it is about to stop, and that it has stopped and should clean up.
Providing both makes it easy to not make mistakes with the global event bus, and still giving a hook for more fine grained issues (long running RPC calls), but the problem can be solved with either solution.
The event handlers are separate object instances that are set and stored against some kind of collection inside the EventBus. Your presenter just creates them and passes them to the EventBus, so the handlers are still referenced beyond the lifetime of the presenter (and that's why they keep running). The presenters are probably not being garbage collected because the handlers may still reference them or their fields.
Having a new presenter created adds the handlers again every time as you've detected, so the solution is to either clear the existing handlers prior to instantiating the new presenter or to keep track of them and not add new handlers when they're already added.
The approach I take is to reuse the screen-level View/Presenter instances and reset their state when re-entering. This also helps with performance. The presenters also keep track of the HandlerRegistration instances for all handlers they add to the EventBus.
I wasn't aware of ResettableEventBus that Colin mentions, but that sounds like a good solution as well.

Java: finalizer for a class?

I have a class that has a static reference to Spring's ApplicationContext. I need to clear that context and run destroy method of its singleton beans when the class is about to be unloaded. So, is there some class level finalizer callback that is called when the class is unloaded, so I can clear the context in that callback?
I have a vague idea of using WeakReferenceQueue and a counter to keep track of un-referenced objects of that class so I can detect when the class has no live objects, but that still won't tell me when the class itself is unloaded.
So, is there some class level finalizer callback that is called when the class is unloaded.
I looked in the obvious places and as far as I can tell, there isn't such a callback. And I can't think of a way to implement one, apart from hacking the JVM itself.
The way to "unload a class" is to have all classes unreachables and the ClassLoader that loaded them too. See Unloading classes in java? for a complete explanation of this process.
A Class is an object like any other in Java. So the classic call to finalizer() is implemented for classes too. This method is called by the Garbage Collector, not you explicitly.
There are no other standard way to unload classes or objects in Java. You can do it by yourself by implementing a method (say "dispose()" for example) that could do some actions if no other object references the object containing dispose() (known as "RefCount").
To know the current refcount of an object or really force garbage collection, you've got to use JVM Tool Interface.
You could also try to call System.runFinalization() but no guarantee is given by the JVM that all finalizers will be called.

Accessing modal dialog variable after calling dispose method

Situation: a main form calls a modal jDialog with textboxes in which parameters are filled in by the user to create or modify an instance of a certain class, call it ClassA.
When the dialog needs to modify an existing instance, it is passed in the constructor as a parameter. Otherwise the jDialog will create a new instance of ClassA.
Problem: the mainform needs to access that new instance, and I think it is unclean code to pass the entire main form as a parameter, and let the dialog push the new instance into it by a method call, because that way a perfectly re-usable stand-alone dialog becomes only usable with one single main form that needs a certain classname and method to receive the new instance.
It is much more logical to make the main form get the new instance from the jdialog after the OK button is clicked, by calling a getClassAInstance() method (which could be called also when an existing instance was being modified). The method is called after the "setVisible(true)" method on a new instance of the jdialog in question. The dialog appears, the thread of the main form will sleep until the dialog is closed (because it is modal). The OK button calls the dispose() method of the jDialog, then the very next statement is the getClassAInstance() call on the jDialog by the mainform.
Here's the same thing in code..
ClassAInstanceMakerDialog imd = new ClassAInstanceMakerDialog(this, true);
imd.setVisible(true);
//imd.dispose(); after OK button click
System.out.println(imd.getClassAInstance()); //return a new ClassA instance
//output: whatever ClassA.toString() should return, works fine
Question: I've tried it and it seems to work perfectly fine. But, is it a good code? Is there any danger of the getClassAInstance() method returning "null", because the garbage collector collected the ClassA instance after the jDialog was disposed and before the main form could complete the call?
Please excuse me if I didn't make myself clear, I'm not a native English speaker. If you would rather see some code, let me know...
I think it's perfectly legal to access the member variable of your dialog instance that holds the ClassA instance, the dialog instance will not be garbage collected until it goes out of scope, not just because you called dispose on it.
I'd give slight preference to a solution where you define an event handler interface with a signature of
someThingHappened(ClassA toThisObject), make your mainform or anything that might be interested that ClassA thing implement that interface make it possible to add listeners to the dialog before making it visible.
That way, you would loosen the coupling between the dialog and the main form a little.
I don't think that dispose() sets the JDialog up for garbage collection, but instead just releases resources. The dialog is still re-usable as per the Window API (since JDialog inherits this method from Window):
Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.
The Window and its subcomponents can be made displayable again by rebuilding the native resources with a subsequent call to pack or show. The states of the recreated Window and its subcomponents will be identical to the states of these objects at the point where the Window was disposed (not accounting for additional modifications between those actions).
Note: When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate. See AWT Threading Issues for more information.
As long as there are valid reachable references to the JDialog object still present, it will not be garbage collected. I think that the cost of disposing the dialog is that your code will need to spend a (very) little bit of time to re-create the resources.
It is perfectly reasonable and appropriate to have an IDisposable include properties or methods which may be used after Dispose is called to return information about things which happened before Dispose was called. Rather than blindly enforcing a rule that any and all methods of a disposed object should throw an ObjectDisposedException, one should instead consider which methods and properties do or do not make sense on disposed objects. Attempting to access a disposed object should throw ObjectDisposedException in preference to re-acquiring released resources or letting escape some other exception which occurs as a consequence of the disposal. If the method or property access can succeed without any of the released resources, it should often be allowed to do so.

I'm pretty sure finalize is still bad news on later JVMs--is there an alternative?

I would like to implement a ORM-style system that can save updates to POJOs when they are no longer reachable by the caller.
I thought the reference classes could do it, but they seem to only enqueue the reference after the object has been cleared (I was hoping it was when they were able to be collected), so once enqueued the .get() method will always return null.
I could use a finalizer but last time I checked those were questionable (Not guaranteed to run promptly or run at all)--I believe a combination of finalizers and runShutdownHook() would work but that's getting into fairly swampy territory.
Is there another path I'm not thinking besides the obligatory "Just have the caller call .save() when he's done"?
Are you just trying to avoid having to call save() on every POJO that you modify?
This can be done reliably using a persistence session object, like this:
Open a new session object.
Load objects via the session object. The session object maintains references to all the objects it loads.
Make any changes to the loaded objects. It is not necessary to call a save method on updated objects.
Close the session object. The session saves all of its objects. It might even be fancy enough to keep a copy of clean loaded data, compare all of its objects to the clean data, and save only the ones that have been modified.
And if you don't want to pass session objects through your code, you can take things a step further with the Unit of Work pattern, associating a session object to the current thread:
Start a unit of work. This creates a session object behind the scenes and associates it with the current thread.
Load objects. Whenever an object is loaded, your ORM automatically associates it with a session object based on the current thread.
Make any changes to the loaded objects. It is not necessary to call a save method on updated objects.
Complete the unit of work. This closes the session object, saving all the objects.
This fixes several problems with a reachability based solution:
You are not relying on nondeterministic garbage collections, which may have a long time between runs, or not run at all.
All objects modified in one operation are saved together. If you rely on reachability, different objects modified in the same operation can become unreachable at different times, meaning your modifications can be saved to the database in bits-and-pieces.
Rollback is much easier - just give your session object a rollback() method. With a reachability solution, you would need to remember to call rollback() on every modified POJO if an operation fails, which is really the same as your original problem.
Perhaps see http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html or research the Unit of Work pattern and emulate some of those ideas.
Use the Observer Pattern do build a ClearanceManager and some Destroyables.
IDestroyable is an interface, which is used for the observers it contains the method public void destroy()
The ClearanceManager is the Subject of the Observerpattern. Maybe use Singleton here to ensure you have just one ClearanceManager object in your application.
Use a Set internaly inside the ClearanceManager (not a List to ensure Objects can just be added once)
support an addDestroyable(IDestroyable destoryable) method (and maybe a removeDestroyable one).
During Runtime the Classes for which you need some destructor emulation, can register them self at the ClearenceManager. ClearenceManager.getInstance().addDestroyable(this);
The ClearanceManager has an doClearance() method, which should just be called at the end of the Main method. It iterates threw the private Set and calls destroy() on every IDestroyable object.
Doing it this way you can emulate destructors, without using them, because using destructors you are losing control about the existance of myabe needed object.
You do not know when overwriting finalize, when it is called.
Maybe, if you do not want to call doClearance() in your Main method you can use here, but just here, a real destructor finalize(). Because there are references in the ClearenceManager to the needed Objects, they will not be destroyed first. But maybe mhh, if there are cross references .... better do not use finalize, use doClearance() and have fun with it :)
I think you are barking up the wrong tree here.
All of Java's finalizer and Reference mechanisms based on reachability depend on the garbage collector to determine whether the respective objects are reachable. So if you use any of the Reference mechanisms for some kind of finalization, you run into much the same issues that make finalize a bad idea.
It is technically possible to implement your own mechanisms for doing reachability; e.g. by implementing your own application-specific reference counting. However, it is likely to be expensive, fragile, and make your code look horrible. (Reference counting in Java is likely to be messier and more fragile than in C++, because you can't overload reference assignment operators to ensure that reference counts are adjusted transparently. So every reference assignment needs to be wrapped in a method call.) So I'd say that doing your own reachability analysis is a bad idea.
So, to be practical you need to either:
rethink your design so that you don't do things based on reachability, or
live with the consequences of using finalize.
The first option is clearly the best, IMO.
maybe you can subclass PhantomReference, and store necessary data in it for final actions.

How to detect when an object is no longer referenced

Is there a way to create register a handler that will be called exactly at the time when the last reference to a certain object is released?
An example would be an object that is backed by a physical data file and once the object become unreferenced, the file should be closed and than renamed. It would be nice if this was possible without having to explicitly call a "close" method on that object.
All the notification mechanisms I am aware of from the Weak/Phantom reference area only state that notification will occur at some point in time but there is no gurantee as to when this will happen...
In short, no.
The Java specification explicitly denies you the ability to know when the last reference is released. JVM implementations (and optimizations) depend on this. There is no hook.
From my understanding, and I've looked for some time to find a "destructor" for java objects, there is no way to know when you lose the last reference. Java tracks references to objects but for performance reasons, updates this information only during garbage collection.
The closest thing is the finalize method which should be called during garbage collection but there's no guarantee that it will be called even then.
I think WeakReference does what you want. A WeakReference gets put into the ReferenceQueue as soon as its weakly reachable (i.e. all strong references are gone).
See this article by Ethan Nicholas.
If you are worried about some references not reaching the ReferenceQueue at shutdown, then keep a list of all objects created (using WeakReferences or PhantomReferences). Add a shutdown hook that checks the list for any outstanding references and perform whatever action you need.
Problem is, "How do you implement this, without something holding a reference to the object?"
Even if you could get passed that problem, say with a service we'll call the HandleManager, the HandleManager would then have to create a new reference to the object, to pass to your handler. Then, your handler could either (a) store a reference to it, which would confuse the HandleManager which was expecting to destroy the unreferenced object; or (b) release the reference, which means that the final reference was once again released, which means the Handler has to be called again....
If you need to manage external resources like files, the best you can do in java is a close() function (whatever name you choose). You can use finalize() as a "belt and suspenders" insurance policy, but that has unpredictable timing. So your main line of defense needs to be the close() function.
See my answer Why would you ever implement finalize()?
This cannot be done with Java -- it needs a reference-counting garbage collector as far as I can tell. Have you considered opening and closing your object's physical data file as needed, rather than keeping it open for the lifetime of the object?
You could override finalize() in your object, but that is problematic for reasons others have mentioned.
For your specific example, you could take a look at using something like File.deleteOnExit(), which would remove the file once the VM exits.

Categories