我正在编写一个插件,它根据规则重构项目的整个代码库。由于我想自动测试它,我正在用jUnit编写一些测试。
现在,对于每个测试,我需要设置工作区,创建测试项目,添加一些文件,然后对它们应用重构。如果我只有一个测试,这完全正常,但是一旦我编写第二个测试方法,我得到一个Java Model Exception: Core Exception [code 274] The file is not synchronized with the local file system.
我认为问题与仍在内存中的文件有关,但未正确删除。我尝试了各种删除和刷新项目的方法,但它们都没有完美运行(尽管文件系统中的内容被删除)。
有人知道如何解决这个问题吗?
设置-方法:
@Before
public void setup() {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
iProject = root.getProject("MyProject");
try {
iProject.create(null);
iProject.open(null);
IProjectDescription description = iProject.getDescription();
description.setNatureIds(new String[] { JavaCore.NATURE_ID });
iProject.setDescription(description, null);
iJavaProject = JavaCore.create(iProject);
IFolder binFolder = iProject.getFolder("bin");
binFolder.create(true, true, null);
iJavaProject.setOutputLocation(binFolder.getFullPath(), null);
sourceFolder = iProject.getFolder("src");
sourceFolder.create(true, true, null);
IClasspathEntry[] buildPath = {
JavaCore.newSourceEntry(iProject.getFullPath()
.append("src")),
JavaRuntime.getDefaultJREContainerEntry() };
iJavaProject.setRawClasspath(buildPath, iProject.getFullPath()
.append("bin"), null);
// create package
iPackage = iJavaProject.getPackageFragmentRoot(sourceFolder)
.createPackageFragment(PACKAGE_NAME, false, null);
//create the java class
ICompilationUnit iUnitUtilityClass = iPackage.createCompilationUnit("Bars.java", existingUtilityClass, false, null);
....
//more files
清理方法:
@After
public void cleanup() throws CoreException, InterruptedException {
//various ways of deleting the project
iProject.delete(true, true, null);
iProject.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT | IResource.DEPTH_INFINITE, new NullProgressMonitor());
ResourcesPlugin.getWorkspace().delete(new IResource[] {iProject.getProject()}, true, null);
iProject = null;
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
root.delete(true, true, null);
}
试验方法: ....
ICompilationUnit iUnit = iPackage.createCompilationUnit("Bar.java",
fileName, false, null);
MoveUtilityMethodsToUtilityClassHandler handler= new MoveUtilityMethodsToUtilityClassHandler();
iUnit.save(null, true);
Result result = handler.handle(iUnit); //<--- here, the exception is thrown
....
例外:
Java Model Exception: Core Exception [code 274] The file is not synchronized with the local file system.
at org.eclipse.jdt.internal.core.BatchOperation.executeOperation(BatchOperation.java:50)
at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:728)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2345)
at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:5332)
at org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange.perform(DynamicValidationStateChange.java:116)
at org.eclipse.ltk.core.refactoring.CompositeChange.perform(CompositeChange.java:278)
at ch.ergon.advancedrefactoring.handlers.MoveUtilityMethodsToUtilityClassVisitor.moveTo(MoveUtilityMethodsToUtilityClassVisitor.java:293)
at ch.ergon.advancedrefactoring.handlers.MoveUtilityMethodsToUtilityClassVisitor.visit(MoveUtilityMethodsToUtilityClassVisitor.java:121)
at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:489)
at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2514)
at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2585)
at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:484)
at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2514)
at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2585)
at org.eclipse.jdt.core.dom.CompilationUnit.accept0(CompilationUnit.java:220)
at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2514)
at ch.ergon.advancedrefactoring.handlers.MoveUtilityMethodsToUtilityClassHandler.handle(MoveUtilityMethodsToUtilityClassHandler.java:45)
at ch.ergon.advancedrefactoring.UtilityRefactorTest.testMoveToExistingUtiliyClass(UtilityRefactorTest.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
答案 0 :(得分:0)
错误消息显示有人在未告知Eclipse的情况下更改了文件。因此,您需要查找使用普通Java API修改文件的代码或在测试或Eclipse之外运行的代码以及更改文件的代码(如Windows上的文件索引器)。
您还可以尝试使用IResource的refreshLocal()
强制刷新。
答案 1 :(得分:0)
我用一个肮脏的解决方法解决了问题(好吧,不是真的)。
由于项目没有被彻底删除,我只为我创建的每个项目使用不同的名称。
因此,在第一次测试中,项目在第二次测试&#34; Project1&#34;中命名为&#34; Project0&#34;,依此类推。这很有效。
@Before
public void setup() {
projectName = "Project" + projectCount++;
System.out.println("Create Project " + projectName);
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
iProject = root.getProject(projectName);
try {
iProject.create(null);
.....
不是我最喜欢的解决方案,但它确实有效......而且Eclipse无论如何都会在测试后清理工作区。