Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » Applying a change and related undo throws exception!
icon4.gif  Applying a change and related undo throws exception! [message #654528] Wed, 16 February 2011 08:42 Go to next message
Kivanc Muslu is currently offline Kivanc MusluFriend
Messages: 153
Registered: November 2010
Senior Member
Edit: More information: My problematic change is instanceof RenameCompilationUnitChange.

Hi all,

Let's say that I have the following class:
 public class WrongClassNameDefinately {} 

defined in a file called WrongClassName.java

In this case (as a user), Eclipse creates a quick fix with 2 proposal:
http://www.kivancmuslu.com/proposals.png

Let's assume that I applied 'Change compilation name to WrongClassNameDefinately.java'. In this case, Eclipse deleted the current file and creates a new file with almost same content in the same package. If, after this quick fix application, I press cmd+z (undo), then Eclipse correctly fixes things back.

I want to do the same thing using the Eclipse API programmatically. What I want (at higher level) is the following:
1- Apply Change that represents 'Change compilation unit to ...' using Change.perform(). This change is retrieved using QuickFixProcessor and going through ChangeCorrectionProposal. Performing the change also creates the undo.
2- Do some calculation. This is not time consuming.
3- Apply the undo.

If I execute the above algorithm for the above change, I always get the following exception (while trying to apply the undo):
WrongClassName.java [in <default> [in src [in -630562215_0]]] does not exist
	org.eclipse.jdt.internal.core.MultiOperation.processElements(MultiOperation.java:175)
	org.eclipse.jdt.internal.core.CopyResourceElementsOperation.processElements(CopyResourceElementsOperation.java:417)
	org.eclipse.jdt.internal.core.MultiOperation.executeOperation(MultiOperation.java:90)
	org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:728)
	org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
	org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:793)
	org.eclipse.jdt.internal.core.JavaModel.rename(JavaModel.java:285)
	org.eclipse.jdt.internal.core.CompilationUnit.rename(CompilationUnit.java:1264)
	org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange.doRename(RenameCompilationUnitChange.java:59)
	org.eclipse.jdt.internal.corext.refactoring.AbstractJavaElementRenameChange.perform(AbstractJavaElementRenameChange.java:86)
	edu.uw.quickfix.speculation.util.Aux.performChangeAndSave(Aux.java:495)
	edu.uw.quickfix.speculation.util.QuickFixPreCalculator.applyUndo(QuickFixPreCalculator.java:351)
	edu.uw.quickfix.speculation.util.QuickFixPreCalculator.processProposal(QuickFixPreCalculator.java:275)
	edu.uw.quickfix.speculation.util.QuickFixPreCalculator.processProblemLocation(QuickFixPreCalculator.java:223)
	edu.uw.quickfix.speculation.util.QuickFixPreCalculator.doWork2(QuickFixPreCalculator.java:201)
	edu.uw.quickfix.speculation.util.BlockableMortalThread.doWork(BlockableMortalThread.java:98)
	edu.uw.quickfix.speculation.util.MortalThread.run(MortalThread.java:44)


By sheer luck, I discovered that (while debugging), this does not happen if there is a delay between change application and undo application. So, if I change the algorithm to below:
1- Apply Change that represents 'Change compilation unit to ...' using Change.perform(). This change is retrieved using QuickFixProcessor and going through ChangeCorrectionProposal. Performing the change also creates the undo.
2- Do some calculation. This is not time consuming.
3- Thread.sleep(100)
4- Apply the undo.

Then the same code works without any problems at all. This is great, however I have 2 problems (questions):
1- For somebody understands the internal of change and undo application, what is the reason beyond this? Thread.yield() or a lower value for sleep (like 10) does not seem to work. I also have no idea if 100 is a valid value for all changes, or if the wait value is change specific.
2- My plugin should compute 50-100 changes in a pass. I am well aware that only changes that create this problem (up to now) are the changes that actually delete and create files or folders, however even for this subset sleeping 100 milliseconds for each proposal is a great performance issue for me. Is there another workaround for this problem I am having?
3- Is there a way to distinguish these category of Changes (that delete and create files and folders)? Like, are they extend a common class that I can check, so that I will only sleep for these instances?

Thanks in advance, best regards,

[Updated on: Wed, 16 February 2011 09:11]

Report message to a moderator

Re: Applying a change and related undo throws exception! [message #655160 is a reply to message #654528] Fri, 18 February 2011 14:10 Go to previous messageGo to next message
Markus KellerFriend
Messages: 294
Registered: July 2009
Senior Member
That should not happen. A problem could be that not all changes are
performed in the same thread and the workspace state is not fully
synchronized. A random delay could help resolving this, but that's not
reliable and there's no "recommended delay" as such.

Since this doesn't seem to work as it should, I also can't give you a
set of problematic Change implementations. You'd have to find these by
trial-and-error and then walk the CompositeChange tree to find
problematic ones.

If you could strip down the problem into a self-contained example, that
would make a great bug report. Top-notch would be a test case like
org.eclipse.jdt.ui.tests.refactoring.RenameResourceChangeTes ts.

HTH,
Markus
Re: Applying a change and related undo throws exception! [message #655291 is a reply to message #655160] Sat, 19 February 2011 00:29 Go to previous message
Kivanc Muslu is currently offline Kivanc MusluFriend
Messages: 153
Registered: November 2010
Senior Member
Hi Markus,

Thanks for the reply.

All changes are done by my background thread (i.e., a daemon), however to make a change applicable, before applying a change, I first open the file in Eclipse editor using Eclipse UI thread. I don't think this would create the problem since it doesn't create a problem with other changes (that does not delete or create files), and the API I use to execute code in Eclipse UI thread is blocking (i.e., it blocks my daemon until Eclipse UI thread opens the file in the editor).

As I described, I don't think that I can generate a user test case for this (since you cannot move the mouse or click keyboard as fast as a program can do). However, I think I can create a simple program that always throws an exception when trying to apply a RenameCompilationUnit change to a file and trying to undo it.

I am not sure how simple the problem I can create can be though. I use the QuickFixProcessor of Eclipse itself to get the IJavaCompletionProposal (which is a ChangeCorrectionProposal) and get Change and Undo objects that represents the modification. I have never tried coding them from scratch.

Would a simple example (i.e., plug-in) with a simple project in its workspace that would throw an exception every time a quick fix is clicked help as a bug report? Or should I make it completely non-interactive (i.e., all Change, Undo etc., are calculated in advance, and program applies it directly).

By the way, do you know why the file that the Change will be applied must be open in an Eclipse editor (if not the change is not applied, neither I receive a notification or exception)? I also find out this by luck.

Thank you,

[Updated on: Sat, 19 February 2011 00:30]

Report message to a moderator

Previous Topic:Phantom errors (Android)
Next Topic:Tasks not refreshing
Goto Forum:
  


Current Time: Fri Apr 26 03:22:45 GMT 2024

Powered by FUDForum. Page generated in 0.03023 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top