Eclipse 強大的搜尋建立在 Lucene 索引之上,僅涵蓋工作區原始碼。專案依賴的 JAR 內 .class 反編譯原始碼、.properties 等資源檔無法被檢索。RCP 開發中常需追蹤 UI 字串定義於哪個 JAR 的哪個檔案,本文提供基於 JDT API 的解決方案。
IJavaProject → 多個 JarPackageFragmentRoot (JAR)JarPackageFragmentRoot → PackageFragment (套件)、JarEntryDirectory (資料夾)、JarEntryFile (檔案)PackageFragment → IClassFile、JarEntryFile

JarPackageFragmentRoot 列表。IClassFile.getSource() 取得反編譯原始碼;JarEntryFile.getContents() 讀取資源檔文字。IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (IProject p : projects) {
IJavaProject jp = JavaCore.create(p);
if (jp != null && jp.exists()) { /* process */ }
}
for (IJavaElement el : jp.getChildren()) {
if (el instanceof JarPackageFragmentRoot) {
JarPackageFragmentRoot jar = (JarPackageFragmentRoot) el;
// 過濾 JRE 系統庫
IClasspathEntry cpe = jar.getRawClasspathEntry();
IClasspathContainer container = JavaCore.getClasspathContainer(cpe.getPath(), jp);
if (container.getKind() == IClasspathContainer.K_DEFAULT_SYSTEM) continue;
searchJar(jar);
}
}
void searchJar(JarPackageFragmentRoot root) {
for (IJavaElement pack : root.getChildren()) {
if (pack instanceof PackageFragment) {
for (IJavaElement cls : ((PackageFragment)pack).getChildren()) {
if (cls instanceof IClassFile) {
searchClassFile((IClassFile)cls);
}
}
}
}
// 非 Java 資源
searchNonJavaResources(root);
}
void searchClassFile(IClassFile cf) {
String src = cf.getSource(); // 需已綁定 Source Attachment
if (src != null) {
Matcher m = pattern.matcher(src);
while (m.find()) {
report(cf.getPath(), m.start(), m.group().length());
}
}
}
void searchNonJavaResources(Object container) {
Object[] res = container instanceof JarPackageFragmentRoot ?
((JarPackageFragmentRoot)container).getNonJavaResources() :
((JarEntryDirectory)container).getChildren();
for (Object o : res) {
if (o instanceof JarEntryDirectory) searchNonJavaResources(o);
else if (o instanceof JarEntryFile) searchJarEntryFile((JarEntryFile)o);
}
}
void searchJarEntryFile(JarEntryFile f) {
try (ByteArrayInputStream in = (ByteArrayInputStream) f.getContents()) {
byte[] bs = new byte[in.available()];
in.read(bs);
String txt = new String(bs);
Matcher m = pattern.matcher(txt);
while (m.find()) report(f.getFullPath(), m.start(), m.group().length());
} catch (Exception e) { /* log */ }
}
gui.properties 於某 JAR。com.ibm.btools.blm.ui.attributesview.resource.gui (Package + 檔名) → 找到使用該 ResourceBundle 的類別 BLMAttributesviewMessageKeys。

| 類別 | 方法 | 說明 |
|---|---|---|
| IClassFile | isClass(), isInterface() | 判斷類型 |
| PackageFragment | getCompilationUnits(), getClassFiles() | 取得 Java/Class 檔列表 |
| JarPackageFragmentRoot | getJar(), getKind(), isArchive(), isReadOnly() | JAR 元資料 |
利用 JDT API 可突破 Eclipse 預設搜尋限制,深入 JAR 內部檢索原始碼與資源。歡迎優化效能 (如建立索引快取) 或封裝為外掛發佈,造福更多 Java/RCP 開發者。