添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

eclipse rcp 需要增加自动update功能,希望使用Equinox P2的api来做相应的自动启动更新,不需要用户的干预.

参考: https://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application

https://git.eclipse.org/c/equinox/rt.equinox.p2.git/tree/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate

查看官方文档,下载git代码,就是跑不通.

偶尔发现一片文章: http://javaarm.com/faces/display.xhtml?tid=3455&page=1

讲的非常详细,一步一步下来,基本上实现了菜单更新.

下面需要实现无干预的更新,

参考: http://www.vogella.com/tutorials/EclipseP2Update/article.html#tutorial_updatelocation

最终实现代码如下:

ApplicationWorkbenchWindowAdvisor:

package com.xsej.office;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.operations.UpdateOperation;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import com.xsej.office.utils.P2Util;
public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
	private static final String JUSTUPDATED = "justUpdated";
	public ApplicationWorkbenchWindowAdvisor(
			IWorkbenchWindowConfigurer configurer) {
		super(configurer);
	public ActionBarAdvisor createActionBarAdvisor(
			IActionBarConfigurer configurer) {
		return new ApplicationActionBarAdvisor(configurer);
	public void preWindowOpen() {
		IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
		int screenWidth = Display.getCurrent().getBounds().width;
		int screenHeight = Display.getCurrent().getBounds().height;
		configurer.setInitialSize(new Point(screenWidth, screenHeight));
		configurer.setShowCoolBar(true);
		configurer.setShowStatusLine(true);
		configurer.setShowProgressIndicator(true);
		configurer.setTitle("example");
	public void postWindowOpen() {
		IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
		configurer.getWindow().getShell().setMaximized(true);
		final IProvisioningAgent agent = (IProvisioningAgent) ServiceHelper
				.getService(Activator.bundleContext,
						IProvisioningAgent.SERVICE_NAME);
		if (agent == null) {
			LogHelper
					.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
							"No provisioning agent found.  This application is not set up for updates."));
		// XXX if we're restarting after updating, don't check again.
		final IPreferenceStore prefStore = Activator.getDefault()
				.getPreferenceStore();
		if (prefStore.getBoolean(JUSTUPDATED)) {
			prefStore.setValue(JUSTUPDATED, false);
			return;
		// XXX check for updates before starting up.
		// If an update is performed, restart. Otherwise log
		// the status.
		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				IStatus updateStatus = P2Util.checkForUpdates(agent, monitor);
				if (updateStatus.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
//					PlatformUI.getWorkbench().getDisplay()
//							.asyncExec(new Runnable() {
//								public void run() {
//									MessageDialog.openInformation(null, "提示",
//											"已经是最新版本");
//								}
//							});
				} else if (updateStatus.getSeverity() != IStatus.ERROR) {
					prefStore.setValue(JUSTUPDATED, true);
					PlatformUI.getWorkbench().getDisplay()
							.asyncExec(new Runnable() {
								public void run() {
									MessageDialog.openInformation(null, "提示",
											"更新完成,现在重启");
									PlatformUI.getWorkbench().restart();
					// PlatformUI.getWorkbench().restart();
				} else {
					LogHelper.log(updateStatus);
		try {
			new ProgressMonitorDialog(null).run(true, true, runnable);
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			LogUtil.log(this.getClass(),e.toString() );
		} catch (InterruptedException e) {
			e.printStackTrace();
			LogUtil.log(this.getClass(),e.toString() );
		} catch (Exception e) {
			e.printStackTrace();
			LogUtil.log(this.getClass(),e.toString() );
	public boolean preWindowShellClose() {
		return true;
 

 P2Util:

package com.xsej.office.utils;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.operations.ProvisioningJob;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
import org.eclipse.equinox.p2.operations.UpdateOperation;
public class P2Util {
	private static final String REPOSITORY_LOC = System.getProperty(
			"P2Util.Repo", "http://127.0.0.1:8080/repository");
	// XXX Check for updates to this application and return a status.
	public static IStatus checkForUpdates(IProvisioningAgent agent,
			IProgressMonitor monitor) throws OperationCanceledException {
		ProvisioningSession session = new ProvisioningSession(agent);
		// the default update operation looks for updates to the currently
		// running profile, using the default profile root marker. To change
		// which installable units are being updated, use the more detailed
		// constructors.
		UpdateOperation operation = new UpdateOperation(session);
		configureUpdate(operation);
		SubMonitor sub = SubMonitor.convert(monitor, "正在检查更新...", 200);
		IStatus status = operation.resolveModal(sub.newChild(100));
		if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
			return status;
		if (status.getSeverity() == IStatus.CANCEL)
			throw new OperationCanceledException();
		if (status.getSeverity() != IStatus.ERROR) {
			// More complex status handling might include showing the user what
			// updates
			// are available if there are multiples, differentiating patches vs.
			// updates, etc.
			// In this example, we simply update as suggested by the operation.
			ProvisioningJob job = operation.getProvisioningJob(null);
			status = job.runModal(sub.newChild(100));
			if (status.getSeverity() == IStatus.CANCEL)
				throw new OperationCanceledException();
		return status;
	private static UpdateOperation configureUpdate(
			final UpdateOperation operation) {
		// create uri and check for validity
		URI uri = null;
		try {
			uri = new URI(REPOSITORY_LOC);
		} catch (final URISyntaxException e) {
			return null;
		LogUtil.log("更新地址:"+uri.toString() );
		// set location of artifact and metadata repo
		operation.getProvisioningContext().setArtifactRepositories(
				new URI[] { uri });
		operation.getProvisioningContext().setMetadataRepositories(
				new URI[] { uri });
		return operation;
 

1.构建整理,原来只是一个plugin工程,但是最后演变成三个工程,原来的plugin工程,feature工程,product工程.

    主要p2需要针对feature进行update.

2.自动更新需要使用equinox p2的api进行无干预更新,那么在plugin中就需要导入相关的插件

Plug-inDescription
org.eclipse.equinox.p2.coreCore p2 functionality
org.eclipse.equinox.p2.engineThe engine carries out the provisioning operation.
org.eclipse.equinox.p2.operationsLayer over the core and engine API to describe updates as an atomic install.
org.eclipse.equinox.p2.metadata.repositoryContains the definition of p2 repositories.

需要添加另外更新需要使用的插件;

  org.eclipse.equinox.p2.touchpoint.natives

  org.eclipse.equinox.p2.transport.ecf

在feature中包含整个p2的featrue包

org.eclipse.equinox.p2.core.featureFeature containing the p2 bundles.

 开发过程因为没有加入org.eclipse.equinox.p2.metadata.repository,导致无法下载新的版本,但是日志没有任何显示,浪费很多时间

eclipse rcp 需要增加自动update功能,希望使用Equinox P2的api来做相应的自动启动更新,不需要用户的干预. 参考:https://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Applicationhttps://git.eclipse.org/c/equinox/rt.equinox.p...
最近基于eclipse 3.6开发RCP程序,不借用eclipse的更新UI,而是在程序启动时自动检查更新,也就是所谓的headless update. 其实这是很简单的,利用eclipse wiki上的一段代码就可以搞定,如下: public class P2Util { static final String JUSTUPDATED = "update_flag";...