2010-10-12 82 views
2

我有一個個人Eclipse RCP產品(com.example.product),它基於一個個人功能(com.example.feature),它由一個個人插件(com.example.plugin)和Eclipse Helios(3.6)中的一些人組成。我希望應用程序檢查更新並根據需要從p2網站進行更新。我希望它是無頭的,即用戶不會在更新過程中進行交互,但可能會在對話框中看到進度。Eclipse RCP 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 Editor中的Create an Update Site Project選項創建我的更新站點。我添加我的`com.example.feature'並構建它。只是爲了看看它是否有效,我嘗試通過eclipse IDE安裝新軟件選項瀏覽它,我可以在那裏看到這個功能。

我構建了更新站點,並將所有3個ID更改爲1.0.1。當我啓動應用程序時,它表示沒有安裝更新,日誌中沒有錯誤。

我不知道爲什麼它不從更新站點更新,但已越過我的腦海的事情是:

1)我可能需要在p2.inf文件的詳細信息,但我不確定是什麼,也許像命名空間,名稱和範圍,但我找不到一個好的實例。

2)checkForUpdates方法我可能需要做一些配置文件來更改正在更新的可安裝單元。再一次,我只發現了一些暗示這一點的評論,而不是任何示例代碼。

任何提示或想法都在這裏非常感謝,這是吃了很多時間。

回答

1

@ user473284的回答有一些建議,我用,但我不知道,如果他們使用本地Web服務器,而不是試圖指向文件 2明確要求

1))遞增產品版本和使用由導出產品嚮導生成的更新存儲庫。

我從來沒有找到從代碼示例引用的getUpdate方法的實現,所以我無法使用該代碼片段。

上述變化後,我仍然留在應用程序檢測到啓動時沒有更新。調試表明我的存儲庫沒有顯示在會話中。我不得不在代碼中明確添加更新網址,儘管它在p2.inf中並且在功能清單編輯器表單字段中進行了設置。這裏的代碼是這樣的:

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

2

看看這段代碼。用新產品版本重建您的產品並嘗試設置一個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) { 
} 
} 
}); 
+0

@ user473284感謝您的幫助,當您說剛公佈該功能將無法正常工作時,我該如何發佈該產品。您的意思是使用導出產品時生成的存儲庫,而不是從功能清單編輯器創建更新站點? – Alb 2010-10-12 15:06:26

+0

@ user473284嗨,我已經建立了一個本地網絡服務器,並有我的p2.inf和現在指向該功能的更新網址。我試着添加你的代碼,但是我沒有getUpdate(profile,provisioningContext,engine,context)的實現;或知道這些論點來自哪裏?這是來自另一個例子什麼的? – Alb 2010-10-12 15:52:16

0
  1. Web服務器不是必需的,您可以通過文件位置獲取更新。
  2. 也必須更改產品版本。
  3. 您無法使用隨產品導出的更新站點項目版本更新這些功能,但是您可以通過在導出產品中進行一些黑客操作來完成這些功能。
  4. 如果使用(安裝新軟件)選項添加其他功能,則可以使用更新站點項目構建來更新這些功能。

希望這會有所幫助。如果你需要更多的澄清,你可以問。