You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建Eclipse插件中的问题标记?求完整示例项目

完整可运行的Eclipse Java编辑器问题标记示例项目

这个示例实现一个简单的Eclipse插件:检测Java文件中的System.out.println语句,在对应行生成警告标记,并在问题视图中显示。

项目结构

com.example.javamarker/
├── plugin.xml
└── src/
    └── com/
        └── example/
            └── javamarker/
                ├── Activator.java
                ├── JavaMarkerGenerator.java
                └── MarkerBuilder.java

核心代码

1. plugin.xml(插件配置)

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension
         point="org.eclipse.core.resources.builders">
      <builder
            hasNature="true"
            id="com.example.javamarker.builder"
            name="Java Marker Builder">
         <run
               class="com.example.javamarker.JavaMarkerGenerator">
         </run>
      </builder>
   </extension>
   <extension
         point="org.eclipse.core.resources.natures">
      <nature
            id="com.example.javamarker.nature"
            name="Java Marker Nature"
            class="com.example.javamarker.Activator$MarkerNature">
      </nature>
   </extension>
   <extension
         point="org.eclipse.core.resources.markers">
      <markerType
            id="com.example.javamarker.customMarker"
            name="Custom Java Marker"
            super="org.eclipse.core.resources.problemmarker">
         <persistent
               value="true">
         </persistent>
      </markerType>
   </extension>

</plugin>

2. Activator.java(插件激活类)

package com.example.javamarker;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

public class Activator extends AbstractUIPlugin {
	public static final String PLUGIN_ID = "com.example.javamarker";
	private static Activator plugin;

	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	public static Activator getDefault() {
		return plugin;
	}

	public static class MarkerNature implements IProjectNature {
		public static final String NATURE_ID = PLUGIN_ID + ".nature";
		private IProject project;

		@Override
		public void configure() throws CoreException {
			IProjectDescription desc = project.getDescription();
			String[] builders = desc.getBuildSpec();
			for (String builder : builders) {
				if (JavaMarkerGenerator.BUILDER_ID.equals(builder)) {
					return;
				}
			}
			String[] newBuilders = new String[builders.length + 1];
			System.arraycopy(builders, 0, newBuilders, 0, builders.length);
			newBuilders[builders.length] = JavaMarkerGenerator.BUILDER_ID;
			desc.setBuildSpec(newBuilders);
			project.setDescription(desc, null);
		}

		@Override
		public void deconfigure() throws CoreException {
			IProjectDescription desc = project.getDescription();
			String[] builders = desc.getBuildSpec();
			for (int i = 0; i < builders.length; i++) {
				if (JavaMarkerGenerator.BUILDER_ID.equals(builders[i])) {
					String[] newBuilders = new String[builders.length - 1];
					System.arraycopy(builders, 0, newBuilders, 0, i);
					System.arraycopy(builders, i + 1, newBuilders, i, builders.length - i - 1);
					desc.setBuildSpec(newBuilders);
					project.setDescription(desc, null);
					return;
				}
			}
		}

		@Override
		public IProject getProject() {
			return project;
		}

		@Override
		public void setProject(IProject project) {
			this.project = project;
		}
	}
}

3. JavaMarkerGenerator.java(标记生成逻辑)

package com.example.javamarker;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

public class JavaMarkerGenerator extends IncrementalProjectBuilder {
	public static final String BUILDER_ID = Activator.PLUGIN_ID + ".builder";
	private static final String MARKER_TYPE = Activator.PLUGIN_ID + ".customMarker";

	@Override
	protected IProject[] build(int kind, @SuppressWarnings("rawtypes") Map args, IProgressMonitor monitor)
			throws CoreException {
		if (kind == FULL_BUILD) {
			fullBuild(getProject(), monitor);
		} else {
			IResourceDelta delta = getDelta(getProject());
			if (delta == null) {
				fullBuild(getProject(), monitor);
			} else {
				incrementalBuild(delta, monitor);
			}
		}
		return null;
	}

	private void fullBuild(IProject project, IProgressMonitor monitor) throws CoreException {
		project.deleteMarkers(MARKER_TYPE, true, IResource.DEPTH_INFINITE);
		visitResources(project, monitor);
	}

	private void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException {
		delta.accept(deltaResource -> {
			IResource resource = deltaResource.getResource();
			if (resource.getType() == IResource.FILE && resource.getName().endsWith(".java")) {
				try {
					resource.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO);
					generateMarkers((IFile) resource);
				} catch (CoreException | IOException e) {
					e.printStackTrace();
				}
			}
			return true;
		});
	}

	private void visitResources(IResource resource, IProgressMonitor monitor) throws CoreException {
		if (resource.getType() == IResource.FILE && resource.getName().endsWith(".java")) {
			try {
				generateMarkers((IFile) resource);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else if (resource.getType() == IResource.FOLDER || resource.getType() == IResource.PROJECT) {
			for (IResource child : resource.members()) {
				visitResources(child, monitor);
			}
		}
	}

	private void generateMarkers(IFile file) throws IOException, CoreException {
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()))) {
			String line;
			int lineNum = 0;
			while ((line = reader.readLine()) != null) {
				lineNum++;
				if (line.contains("System.out.println")) {
					MarkerBuilder.createMarker(file, lineNum, "避免使用System.out.println进行调试", MARKER_TYPE,
							IResource.DEPTH_ZERO);
				}
			}
		}
	}
}

4. MarkerBuilder.java(标记构建工具类)

package com.example.javamarker;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;

public class MarkerBuilder {
	public static void createMarker(IResource resource, int lineNumber, String message, String markerType, int depth)
			throws CoreException {
		IMarker marker = resource.createMarker(markerType);
		marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
		marker.setAttribute(IMarker.MESSAGE, message);
		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
		marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL);
	}
}

部署与测试

  1. 确保你的Eclipse安装了Plugin Development Environment(PDE),未安装可通过Help → Eclipse Marketplace搜索安装。
  2. 右键项目 → Run As → Eclipse Application,启动新的Eclipse实例。
  3. 在新实例中创建Java项目,右键项目 → Configure → Add Nature,选择"Java Marker Nature"。
  4. 创建Java类,写入System.out.println("test");代码。
  5. 保存文件后,编辑器右侧标记栏会出现黄色警告图标,打开Window → Show View → Problems可查看生成的警告标记。

自定义扩展说明

  • 修改JavaMarkerGenerator.generateMarkers方法中的检测逻辑,即可实现自定义编码规则的检测。
  • 若需替换标记图标,可在项目中添加icons目录放入图标文件,再在plugin.xml中添加org.eclipse.ui.ide.markerImageProviders扩展配置。

内容的提问来源于stack exchange,提问作者zenith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:55:26