Eclipse 插件開發中,自動生成代碼、模型轉換代碼 (UML→Java) 後,必須通知工作區刷新並觸發增量構建,否則生成文件不會被編譯、索引、顯示在 Package Explorer 中。本文給出核心 API 直接可用的代碼片段。
所有可刷新/構建對象實現 org.eclipse.core.resources.IResource:
| 接口 | 代表 | 典型實現類 |
|---|---|---|
| IResource | 統一根接口 | Resource (抽象基類) |
| IContainer | 容器 (項目/文件夾) | Container |
| IProject | 項目 | Project |
| IFolder | 文件夾 | Folder |
| IFile | 文件 | File |
| IWorkspaceRoot | 工作區根 | WorkspaceRoot |
IResource
├─ IContainer
│ ├─ IFolder
│ ├─ IProject
│ └─ IWorkspaceRoot
└─ IFile
void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException
depth:
IResource.DEPTH_ZERO (0) — 僅刷新資源本身IResource.DEPTH_ONE (1) — 刷新資源及直接子成員IResource.DEPTH_INFINITE (2) — 遞歸刷新整棵子樹 (最常用)monitor:進度監控器,可傳 null (無進度上報) 或 new NullProgressMonitor()// 1. 刷新整個項目 (生成代碼後最常用)
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("MyProject");
project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
// 2. 刷新特定文件夾 (如 target/generated-sources)
IFolder folder = project.getFolder("target/generated-sources");
folder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
// 3. 刷新單個文件
IFile file = folder.getFile("GeneratedClass.java");
file.refreshLocal(IResource.DEPTH_ZERO, monitor);
// 4. 刷新整個工作區 (慎用,性能開銷大)
ResourcesPlugin.getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, monitor);
WorkspaceJob job = new WorkspaceJob("刷新生成代碼") {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
return Status.OK_STATUS;
}
};
job.setUser(true); // 用戶可見任務
job.schedule();
IWorkspace.build(int kind, IProgressMonitor monitor)
| 常量 | 值 | 行為 |
|---|---|---|
| 0 | 全量構建 (清理後重建) | |
| 1 | 增量構建 (默認,僅編譯變更) | |
| 2 | 清理構建輸出 (不編譯) | |
| 3 | 觸發自動構建 (若啟用) |
IWorkspace workspace = ResourcesPlugin.getWorkspace();
// 1. Clean All (最徹底)
workspace.build(IncrementalProjectBuilder.CLEAN_BUILD, new NullProgressMonitor());
// 緊接觸發全量構建
workspace.build(IncrementalProjectBuilder.FULL_BUILD, monitor);
// 2. 僅 Clean 單個項目
IProject project = workspace.getRoot().getProject("MyProject");
project.build(IncrementalProjectBuilder.CLEAN_BUILD,
new SubProgressMonitor(monitor, 1)); // 進度分配
// 3. 觸發單項目增量構建
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
// 4. 自動構建模式下,通常無需手動調用
// 但代碼生成後立即需編譯時,建議顯式調用 INCREMENTAL_BUILD
public void generateAndBuild(IProject project, IProgressMonitor monitor) throws CoreException {
try {
// 1. 執行代碼生成邏輯 (寫入文件到項目中)
CodeGenerator.generate(project); // 你的生成邏輯
// 2. 刷新工作區 (讓 Eclipse 感知文件系統變更)
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
// 3. 觸發增量構建 (編譯新生成的 Java 文件)
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
} catch (CoreException e) {
// 回滾或報錯
throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, "生成構建失敗", e));
}
}
若插件需深度集成構建過程 (如自定義編譯器、模型驗證),實現 IncrementalProjectBuilder:
public class MyCustomBuilder extends IncrementalProjectBuilder {
public static final String BUILDER_ID = "com.example.myCustomBuilder";
@Override
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
throws CoreException {
// kind: FULL/INCREMENTAL/CLEAN
if (kind == CLEAN_BUILD) {
clean(monitor);
return null;
}
// 增量構建:獲取變更資源
IResourceDelta delta = getDelta(project);
if (delta == null) { // 全量構建
fullBuild(monitor);
} else {
incrementalBuild(delta, monitor);
}
return null;
}
// 在 plugin.xml 註冊
//
//
//
//
//
}
exists(),避免 CoreException: Resource not foundIProgressMonitor,支持取消/進度顯示WorkspaceJob 或 IWorkspaceRunnable 中運行 (自動獲取寫鎖)derived=true 排除衍生資源掌握 refreshLocal 與 build 核心 API,即可實現「代碼生成即時生效」的流暢插件體驗。