【问题标题】:Eclipse RCP p2 update not workingEclipse RCP p2 更新不起作用
【发布时间】:2011-04-24 02:02:59
【问题描述】:

我有一个基于一个个人功能 (com.example.feature) 的个人 Eclipse RCP 产品 (com.example.product),它由一个个人插件 (com.example.plugin) 和 Eclipse Helios (3.6) 中的一堆其他插件组成。我希望该应用程序检查更新并在必要时从 p2 站点进行更新。我希望它是无头的,即用户不会在更新过程中进行交互,但可能会在对话框中看到进度。

我的更新实现基于RCP Mail application。我稍微更改了P2Util.checkForUpdates 方法以包含一些日志记录,这样我就可以看到那里出了什么问题(如果有的话):

    static IStatus checkForUpdates(IProvisioningAgent agent,
        IProgressMonitor monitor) throws OperationCanceledException,
        InvocationTargetException {
    ProvisioningSession session = new ProvisioningSession(agent);
    UpdateOperation operation = new UpdateOperation(session);
    SubMonitor sub = SubMonitor.convert(monitor,
            "Checking for application updates...", 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) {
        try {
            logger.info( "Status is " + status );
            Update[] updates = operation.getPossibleUpdates();              
            for( Update u : updates){
                logger.info( "Update is " + u );
            }               
            ProvisioningJob job = operation.getProvisioningJob(null);
            if( job == null ){
                logger.error( "Provisioning Job is null" );
            }
            status = job.runModal(sub.newChild(100));
            if (status.getSeverity() == IStatus.CANCEL) {
                throw new OperationCanceledException();
            }
        } catch ( Exception e ){
            logger.error( "Exception while trying to get updates", e);
        }
    }
    return status;
}

我的功能中有一个p2.inf 文件,与我的example.product 文件处于同一级别。它包含:

org.eclipse.equinox.p2.touchpoint.eclipse.addRepository": 
instructions.configure=\ 
org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(type:0,location:file${#58}/C${#58}/workspace/updatesite/);\
org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(type:1,location:file${#58}/C${#58}/workspace/updatesite/);

我构建产品时将插件、功能和产品 ID 设置为 1.0.0。 我可以使用产品导出向导从 eclipse 中导出和运行我的产品。当我这样做时,我会勾选generate metadata repository

我使用 Feature Manfiest 编辑器中的 Create an Update Site Project 选项创建我的更新站点。我添加我的“com.example.feature”并构建它。只是为了看看它是否有效,我尝试通过 eclipse IDE 安装新软件选项浏览它,我可以在那里看到该功能。

我构建更新站点时将所有 3 个 ID 更改为 1.0.1。当我启动应用程序时,它说没有要安装的更新,日志中没有错误。

我不知道为什么它没有从更新站点更新,但我想到的事情是:

1) 我可能需要 p2.inf 文件中的更多信息,但我不确定是什么,可能是命名空间、名称和范围之类的东西,但我找不到好的实用方法例子。

2)checkForUpdates 方法中,我可能需要使用配置文件来更改正在更新的可安装单元。同样,我只发现 cmets 暗示了这一点,没有任何示例代码说明如何。

这里非常感谢任何提示或想法,这会占用很多时间。

【问题讨论】:

    标签: eclipse eclipse-plugin eclipse-rcp p2


    【解决方案1】:

    看看这段代码。使用新的产品版本重建您的产品并尝试设置 http 服务器。它不适用于我的文件回购。仅仅发布该功能是行不通的。

    final IRunnableWithProgress runnable = new IRunnableWithProgress() {
    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
    
    sub = SubMonitor.convert(monitor, Messages.getString("UpdateManager.searchforupdates"), 200); //$NON-NLS-1$
    final Update update = getUpdate(profile, provisioningContext, engine, context);
    
    status = operation.resolveModal(sub.newChild(100));
    LogHelper.log(status);
    if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
     status = null;
     return;
    }
    if (status.getSeverity() == IStatus.CANCEL)
     throw new OperationCanceledException();
    if (status.getSeverity() != IStatus.ERROR) {
     log(IStatus.INFO, "Checking for available update matches", null); //$NON-NLS-1$
     Update[] selected = new Update[1];
     operation.setSelectedUpdates(new Update[0]);
     for (Update available : operation.getPossibleUpdates()) {
      if (available.equals(update)) {
       log(IStatus.INFO, "Update matches available: " + update, null); //$NON-NLS-1$
       selected[0] = available;
       operation.setSelectedUpdates(selected);
      }
     }
     if (selected[0] == null) {
      status = null;
      monitor.setCanceled(true);
    
      log(IStatus.WARNING, "No Update matches selected", null); //$NON-NLS-1$
      return;
     }
     ProvisioningJob job = operation.getProvisioningJob(monitor);
     if (job != null) {
      status = job.runModal(sub.newChild(100));
      if (status.getSeverity() != IStatus.ERROR) {
       prefStore.setValue(JUSTUPDATED, true);
       Display.getDefault().syncExec(new Runnable() {
        public void run() {
         PlatformUI.getWorkbench().restart();
        }
       });
    
      } else {
       LogHelper.log(status);
      }
    
     } else {
      log(IStatus.INFO, "getJob returned null", null); //$NON-NLS-1$
      status = null;
     }
     if (status != null && status.getSeverity() == IStatus.CANCEL)
      throw new OperationCanceledException();
     }
     }
    };
    
    Display.getDefault().asyncExec(new Runnable() {
    public void run() {
    try {
     new ProgressMonitorDialog(null).run(true, true, runnable);
    } catch (InvocationTargetException x) {
     log(IStatus.ERROR, "Runnable failure", x); //$NON-NLS-1$
    } catch (InterruptedException e) {
    }
    }
    });
    

    【讨论】:

    • @user473284 感谢您的帮助,当您说仅发布功能不起作用时,我该如何发布产品。您的意思是使用导出产品时生成的存储库,而不是从功能清单编辑器创建更新站点?
    • @user473284 再次嗨,我已经设置了一个本地 Web 服务器,并且我的 p2.inf 和功能的更新 url 现在指向它。我已尝试添加您的代码,但我没有 getUpdate(profile, provisioningContext, engine, context); 的实现。或者知道这些论点从何而来?这是来自另一个例子还是什么?
    【解决方案2】:

    @user473284 的回答有一些我使用的建议,但我不知道它们是否是明确的要求

    1) 使用本地 Web 服务器而不是尝试指向文件 2) 增加产品版本并使用导出产品向导生成的更新存储库。

    我从未找到代码示例中引用的 getUpdate 方法的实现,因此我无法使用 sn-p。

    在进行了上述更改后,我仍然发现应用在启动时没有检测到更新。调试显示我的存储库没有出现在会话中。尽管在 p2.inf 和功能清单编辑器表单字段中设置了更新 url,但我必须在代码中显式添加更新 url。这是代码:

        public static void addUpdateSite(IProvisioningAgent provisioningAgent)
            throws InvocationTargetException {
        // Load repository manager
        IMetadataRepositoryManager metadataManager = (IMetadataRepositoryManager) provisioningAgent
                .getService(IMetadataRepositoryManager.SERVICE_NAME);
        if (metadataManager == null) {
            logger.error( "Metadata manager was null");
             Throwable throwable = new
             Throwable("Could not load Metadata Repository Manager");
             throwable.fillInStackTrace();
             throw new InvocationTargetException(throwable);
        }
    
        // Load artifact manager
        IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) provisioningAgent
                .getService(IArtifactRepositoryManager.SERVICE_NAME);
        if (artifactManager == null) {
            logger.error( "Artifact manager was null");
            Throwable throwable = new Throwable(
                    "Could not load Artifact Repository Manager");
            throwable.fillInStackTrace();
            throw new InvocationTargetException(throwable);
        }
    
        // Load repo
        try {
            URI repoLocation = new URI("http://localhost/respository");
            logger.info( "Adding repository " + repoLocation );
            metadataManager.loadRepository(repoLocation, null);
            artifactManager.loadRepository(repoLocation, null);
        } catch (ProvisionException pe) {
            logger.error( "Caught provisioning exception " + pe.getMessage(), pe);
            throw new InvocationTargetException(pe);
        } catch (URISyntaxException e) {
            logger.error( "Caught URI syntax exception " + e.getMessage(), e);
            throw new InvocationTargetException(e);
        }
    }
    

    我现在在原始问题的 checkForUpdates 方法中调用这第一件事。在此更改之后,我的应用程序至少现在可以看到更新并尝试安装它。我仍然有问题,但这值得我在https://stackoverflow.com/questions/3944953/error-during-p2-eclipse-rcp-app-headless-update创建一个单独的问题@

    【讨论】:

      【解决方案3】:
      1. Web 服务器不是强制性的,您可以通过文件位置获取更新。
      2. 也必须更改产品版本。
      3. 您无法使用随产品导出的更新站点项目构建来更新这些功能,但是您可以通过在导出的产品中进行一些黑客攻击来做到这一点。
      4. 如果您使用(安装新软件)选项添加了一些其他功能,那么您可以使用更新站点项目构建来更新这些功能。

      希望这会有所帮助。如果您需要更多说明,可以询问。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-12
        • 2010-12-14
        • 2013-03-17
        • 2011-09-27
        • 2011-07-09
        • 2017-07-08
        • 1970-01-01
        相关资源
        最近更新 更多