如何避免“org.eclipse.jdt.core.JavaModelException:Update conflict”

时间:2014-02-10 14:42:22

标签: java eclipse eclipse-jdt

我写了一个插件,对遗留代码进行了一些批量更改。更改在ICompilationUnits集合的循环中完成,逐个处理。多次运行,可能会再次更改相同的编译单元。

如果是第一次运行,该命令可以正常工作。之后,当我再次运行命令时,我得到一个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本身?

1 个答案:

答案 0 :(得分:0)

错误在CommitWorkingCopyOperation.verify

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

hasResourceChanged正在检查存储在编译单元中的时间戳与源文件的时间戳。所以看起来你正在选择一个过时的编译单元。