Hello,
I am in the process of porting our RCP application from 3.5 to Helios 3.6. During my port I discovered that the P2 API has changed significantly and I modified my headless update code to take advantage of the new API along with the UpdateOperation class. I found that updating from a version of our application that is using 3.5 to a version that is using 3.6 works perfectly fine however once I attempt to upgrade once more to another higher version of our application that is using 3.6 I get the following status error report.
!ENTRY org.eclipse.equinox.p2.operations 4 0 2010-07-12 20:19:14.135
!MESSAGE Operation details
!SUBENTRY 1 org.eclipse.equinox.p2.director 4 1 2010-07-12 20:19:14.135
!MESSAGE Cannot complete the install because of a conflicting dependency.
!SUBENTRY 2 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE Software being installed: iSymphony 2.2.0.2131 (isymphony 2.2.0.2131)
!SUBENTRY 2 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE Software currently installed: ClientRCP Plug-in 2.2.0.2130 (ClientRCP 2.2.0.2130)
!SUBENTRY 2 org.eclipse.equinox.p2.director 4 1 2010-07-12 20:19:14.135
!MESSAGE Only one of the following can be installed at once:
!SUBENTRY 3 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE ClientRCP Plug-in 2.2.0.2130 (ClientRCP 2.2.0.2130)
!SUBENTRY 3 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE ClientRCP Plug-in 2.2.0.2131 (ClientRCP 2.2.0.2131)
!SUBENTRY 2 org.eclipse.equinox.p2.director 4 1 2010-07-12 20:19:14.135
!MESSAGE Cannot satisfy dependency:
!SUBENTRY 3 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE From: iSymphony Feature 2.2.0.2131 (iSymphonyFeature.feature.group 2.2.0.2131)
!SUBENTRY 3 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE To: ClientRCP [2.2.0.2131]
!SUBENTRY 2 org.eclipse.equinox.p2.director 4 1 2010-07-12 20:19:14.135
!MESSAGE Cannot satisfy dependency:
!SUBENTRY 3 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE From: iSymphony 2.2.0.2131 (isymphony 2.2.0.2131)
!SUBENTRY 3 org.eclipse.equinox.p2.director 4 0 2010-07-12 20:19:14.135
!MESSAGE To: iSymphonyFeature.feature.group [2.2.0.2131]
Note that if I start with the version that contains 3.6 already I can update to my hearts content. It seems as if p2 is trying to do an install instead of a update. I have attched my update class code below. Is there any additional information I can provide that may be of use in assisting me with resolving this issue?
Best Regards,
Mike
package com.xmlnamespace.operatorpanel.update;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.concurrent.Semaphore;
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.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.operations.ProvisioningJob;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
import org.eclipse.equinox.p2.operations.Update;
import org.eclipse.equinox.p2.operations.UpdateOperation;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
@SuppressWarnings("restriction")
public class Updater {
//Shell
private Shell shell = null;
//Update lock semaphores
private Semaphore updateLock = null;
//Update workers
private IProvisioningAgent provisioningAgent = null;
private IMetadataRepositoryManager metadataManager = null;
private IArtifactRepositoryManager artifactManager = null;
//Constructor------------------------------------------------------------------------------------------------------------------------------------
public Updater(Shell shell) {
this.shell = shell;
updateLock = new Semaphore(1);
}
//Update methods---------------------------------------------------------------------------------------------------------------------------------
public void updateFromURL(String updateLocation) {
try {
URI uri = new URL(updateLocation).toURI();
//If an update occurred prompt for restart
if(updateCore(uri)) {
openRestart();
}
} catch(URISyntaxException URIse) {
openError(Messages.Updater_update_failed_label, Messages.Updater_update_location_path_malformed_label + ":" + updateLocation);
UpdateLog.logErrorNoPopup(Messages.Updater_update_failed_label + ":" + updateLocation, URIse);
} catch(MalformedURLException MURLe) {
openError(Messages.Updater_update_failed_label, Messages.Updater_update_location_path_malformed_label + ":" + updateLocation);
UpdateLog.logErrorNoPopup(Messages.Updater_update_failed_label + ":" + updateLocation, MURLe);
}
}
public void updateFromFile(String updateLocation) {
//Check for path existence
File updatePath = new File(updateLocation);
if(updatePath.exists()) {
//If an update occurred prompt for restart
if(updateCore(updatePath.toURI())) {
openRestart();
}
} else {
openError(Messages.Updater_update_failed_label,
Messages.Updater_update_path_does_not_exist_label + ":" + updateLocation);
}
}
private boolean updateCore(final URI repoLocation) {
//Create update progress bar runnable
IRunnableWithProgress updateProgressRunnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
//Check if repo location was provided
if(repoLocation == null) {
Throwable throwable = new Throwable(Messages.Updater_no_repositories_provided_label);
throwable.fillInStackTrace();
throw new InvocationTargetException(throwable);
}
//Load provisioning agent
provisioningAgent = (IProvisioningAgent) ServiceHelper.getService(Activator.bundleContext, IProvisioningAgent.SERVICE_NAME);
if (provisioningAgent == null) {
Throwable throwable = new Throwable(Messages.Updater_could_not_load + " Provisioning Agent");
throwable.fillInStackTrace();
throw new InvocationTargetException(throwable);
}
//Load repository manager
metadataManager = (IMetadataRepositoryManager) provisioningAgent.getService(IMetadataRepositoryManager.SERVICE_NAME);
if(metadataManager == null) {
Throwable throwable = new Throwable(Messages.Updater_could_not_load + " Metadata Repository Manager");
throwable.fillInStackTrace();
throw new InvocationTargetException(throwable);
}
//Load artifact manager
artifactManager = (IArtifactRepositoryManager) provisioningAgent.getService(IArtifactRepositoryManager.SERVICE_NAME);
if(artifactManager == null) {
Throwable throwable = new Throwable(Messages.Updater_could_not_load + " Artifact Repository Manager");
throwable.fillInStackTrace();
throw new InvocationTargetException(throwable);
}
//Convert monitor
SubMonitor mainMonitor = SubMonitor.convert(monitor, "Checking for application updates...", 300);
//Load repo
try {
metadataManager.loadRepository(repoLocation, null);
artifactManager.loadRepository(repoLocation, null);
} catch (ProvisionException pe) {
throw new InvocationTargetException(pe);
}
//Create update session and operation
ProvisioningSession session = new ProvisioningSession(provisioningAgent);
UpdateOperation operation = new UpdateOperation(session);
//Check for updates
IStatus status = operation.resolveModal(mainMonitor.newChild(100));
//If updates were not found throw exception
if(status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
throw new InvocationTargetException(new NoUpdatesFoundException());
}
//If update was canceled throw exception
if(status.getSeverity() == IStatus.CANCEL) {
throw new OperationCanceledException();
}
//If update check errored out throw exception
if(status.getSeverity() == IStatus.ERROR) {
throw new InvocationTargetException(new StatusException(status));
}
//Execute update
ProvisioningJob job = operation.getProvisioningJob(null);
status = job.runModal(mainMonitor.newChild(100));
if(status.getSeverity() == IStatus.CANCEL) {
throw new OperationCanceledException();
}
//If update check errored out throw exception
if(status.getSeverity() == IStatus.ERROR) {
throw new InvocationTargetException(new StatusException(status));
}
}
};
//Check update lock
if(!updateLock.tryAcquire()) {
return false;
}
//Run update progress dialog
boolean updated = false;
try {
final ProgressMonitorDialog updateProgressDialog = new ProgressMonitorDialog(shell);
updateProgressDialog.open();
updateProgressDialog.getShell().setText("Updating");
updateProgressDialog.run(true, true, updateProgressRunnable);
updated = true;
} catch(InvocationTargetException ite) {
//Show error that occurred
if(ite.getTargetException() instanceof NoUpdatesFoundException) {
openInformation(Messages.Updater_application_up_to_date_label, Messages.Updater_application_is_up_to_date_label);
} else if(ite.getTargetException() instanceof StatusException) {
IStatus status = ((StatusException)ite.getTargetException()).getStatus();
openError(Messages.Updater_update_failed_label, status.getMessage());
UpdateLog.log(status);
} else {
openError(Messages.Updater_update_failed_label, ite.getTargetException().getMessage());
UpdateLog.logErrorNoPopup(Messages.Updater_update_failed_label, ite.getTargetException());
}
} catch(InterruptedException ie) {
//Operation was canceled do nothing
} finally {
//Cleanup
if(metadataManager != null) {
metadataManager.removeRepository(repoLocation);
}
if(artifactManager != null) {
artifactManager.removeRepository(repoLocation);
}
if(provisioningAgent != null) {
provisioningAgent.stop();
}
metadataManager = null;
artifactManager = null;
provisioningAgent = null;
updateLock.release();
}
return updated;
}
//Helper methods---------------------------------------------------------------------------------------------------------------------------------
private void openRestart() {
Display.getDefault().syncExec( new Runnable() {
public void run() {
MessageDialog.openInformation(shell, Messages.Updater_update_successful_label, Messages.Updater_a_restart_is_requierd_for_updates_to_take_effect_label);
}
});
PlatformUI.getWorkbench().restart();
}
private void openError(final String title, final String body) {
Display.getDefault().asyncExec( new Runnable() {
public void run() {
MessageDialog.openError(shell, title, body);
}
});
}
private void openInformation(final String title, final String body) {
Display.getDefault().asyncExec( new Runnable() {
public void run() {
MessageDialog.openInformation(shell, title, body);
}
});
}
}