I debugged the Eclipse many many times and tried to follow the path (the method calls) that lead to the bug. With the aid of documentation, I could successfully find the method calls that lead to the bug. The Following steps were taken by me to find and fix the bug:
1. As mentioned in the previous post , the source of the bug is equals method in the Base.java class, which is called in the serverRemoved in the ServerEditor.java:
public void serverRemoved(IServer oldServer) {
if (oldServer.equals(server) && !isDirty())
closeEditor();
}
2. I find calling isDirty() method is unnecessary. Let me explain what this method does. When any information is modified in the server editor window, "dirty" flag of the server editor is set to "true", and isDrity() method returns the value of the flag (either true or false). This is useful since the user will get prompted to save the modified server editor before closing it.
For now, I decided to remove the call to isDirty() method completely, and I will deal with that later (Updated - Get more information in the next post "Bug Fixing Part 2"). So the modified code is the serverRemoved() method will look like this:
public void serverRemoved(IServer oldServer) {
if (oldServer.equals(server))
closeEditor();
}
3. The IF statement compares an instance of IServer interface that is passed to the method with the member variable (server) , which represents a working copy of the server. The result of this comparison is always "False". To better understand the reason behind it, let's look at the equals method in the Base.Java:
As you see, this method performs various tests to determine if the two instances are equal or not. In the case of our bug, the following line causes that this method concludes that the two instances of the server are NOT equal:
if (isWorkingCopy() != base.isWorkingCopy())
return false;
Each Server instance can have a ServerWorkingCopy instance associated with that.
isWorkingCopy() returns "False" or "True" based on whether the IServer instance is a working copy of the server (ServerWorkingCopy instance) or the actual "Server" instance.
The isWorkingCopy() of the actual Server instance always return "false", and the isWorkingCopy() of ServerWorkingCopy instance always return true.
Based on the above information, and the debugging trace, I observed that "base" object is an instance of ServerWorkingCopy and the current object "this" is the actual Server instance. Therefore, these two instances are never equal.
4. Therefore, to fix the bug I should pass the working copy of the actual "Server" instance to equals() method instead of passing the "Server" object itself.
5. Going back to serverRemoved() method: I debugged the bug path many times and examined the following files in details:
ResourceManager.java
Server.java
IServerLifeCycleList.java
GlobalCommandManager.java
IServer.java
IServerWorkingCopy.java
My goal was to determine whether the "oldServer" object that is passed to serverRemoved() object is the actual "Server" object or its working copy. I figured out that the "oldServer" is the actual "Server" object not its working copy. Therefore, if I can grab the working copy of the "Server" object, I can pass it to equals() method to fix the bug.
5. After investigation of the above java filenames and the documentation, I found out that I can get the working copy of the "Server" object from the GlobalCommandManager. Therefore, I changed the code in the serverRemoved() method to the following code:
public void serverRemoved(IServer oldServer) {
if (commandManager.getServerResource(oldServer.getId()).equals(server))
closeEditor();
}
6. commandManager.getServerResource() method gets a resource id (string) and returns the resource. In this case, I passed the id of the received server (oldServer.getId()), and the method returns a working copy of the server. Therefore, the two instances that are passed to equals() method will be equal. As the result, the server editor will be successfully closed upon deletion of the server.
7. A copy of modified ServerEditor.java can be downloaded from the following link. Just copy this file into your Eclipse Plugin workspace and replace the old file. Then, compile and run the modified code and observe that the bug is fixed.
Modified Copy of ServerEditor.java fixed by Farhad Norouzi
Congratulations, Farhad!
ReplyDeleteYour work will give new momentum to our WTP class
Peter.
Congratulations! :)
ReplyDeleteThe bug I'm working on is involved with the ServerEditor as well. I think I can benefit from your result :).