2014-02-10 204 views
1

我寫了一個插件,對傳統代碼進行一些批量更改。這些更改通過ICompilationUnits的集合循環完成,並逐個處理。多次運行,可能會再次更改相同的編譯單元。如何避免「org.eclipse.jdt.core.JavaModelException:更新衝突」

該命令工作正常,如果第一次運行。之後,當我再次運行命令時,我得到一個JavaModelException

org.eclipse.jdt.core.JavaModelException: Update conflict 
    at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:784) ~[na:na] 
    at org.eclipse.jdt.internal.core.CompilationUnit.commitWorkingCopy(CompilationUnit.java:391) ~[na:na] 
    ... 

我該怎麼做才能避免這種異常?我處理代碼更改的代碼如下所示:

public void process(ICompilationUnit cu, SubMonitor monitor) throws CoreException { 
    monitor.setWorkRemaining(7); 
    try { 
     cu.becomeWorkingCopy(monitor.newChild(1)); 

     CompilationUnit unit = EclipseUtil.parseAst(cu, monitor.newChild(1)); 
     ASTRewrite rewrite = ASTRewrite.create(unit.getAST()); 
     ImportRewrite importRewrite = ImportRewrite.create(unit, true); 

     // Do the Work 
     processSearchResults(unit, rewrite, importRewrite, monitor.newChild(1)); 

     cu.applyTextEdit(rewrite.rewriteAST(), monitor.newChild()); 
     TextEdit importEdit = importRewrite.rewriteImports(monitor.newChild(1)); 
     cu.applyTextEdit(importEdit, monitor.newChild(1)); 

     if (monitor.isCanceled()) 
      cu.discardWorkingCopy(); 
     else 
      cu.commitWorkingCopy(false, monitor.newChild(1)); 
    } catch (Exception e) { 
     cu.discardWorkingCopy(); 
     throw e; 
    } finally { 
     monitor.done(); 
    } 
} 

所有實例都是新鮮閱讀的。插件本身不會緩存任何東西。有沒有我忘記做的事情,比如刷新或關閉資源?也許單位AST本身?在CommitWorkingCopyOperation.verify產生

回答

0

錯誤:

if (cu.hasResourceChanged() && !this.force) { 
    return new JavaModelStatus(IJavaModelStatusConstants.UPDATE_CONFLICT); 
} 

hasResourceChanged被檢查存儲在編譯單元對源文件的時間戳的時間戳。所以看起來你正在挑選一個過時的編譯單元。

+0

嗨格雷格,感謝您的意見。我怎樣才能確保編譯單元得到「刷新」?我看到ICompilationUnit.reconcile(...),但這似乎是別的東西。 –