Обновление Eclipse RCP p2 не работает - PullRequest
2 голосов
/ 12 октября 2010

У меня есть персональный продукт Eclipse RCP (com.example.product), основанный на одной персональной функции (com.example.feature), которая состоит из одного личного плагина (com.example.plugin) и нескольких других из Eclipse Helios (3.6).Я хочу, чтобы приложение проверяло наличие обновлений и само обновлялось при необходимости с сайта p2.Я хочу, чтобы он был без головы, то есть пользователь не взаимодействует в процессе обновления, но может видеть прогресс в диалоговом окне.

Я основал свою реализацию для обновлений в приложении RCP Mail ,Я немного изменил метод 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/);

Я создаю продукт с плагинами, функциями и идентификаторами продуктов, установленными на 1.0.0.Я могу экспортировать и запустить свой продукт из Eclipse, используя мастер экспорта продукта.Я отмечаю generate metadata repository, когда я делаю это.

Я создаю свой сайт обновлений, используя опцию Create an Update Site Project в Редакторе функций Manfiest.Я добавляю свой com.example.feature и собираю его.Просто чтобы посмотреть, работает ли он, я пытаюсь просмотреть его с помощью опции «Установить новое программное обеспечение» в eclipse IDE, и я вижу там функцию.

Я создаю сайт обновления со всеми 3 идентификаторами, измененными на 1.0.1.Когда я запускаю приложение, оно говорит, что нет обновлений для установки, в журналах нет ошибок.

Я не знаю, почему оно не обновляется с сайта обновлений, но что-то пересекало мойпомните:

1) Мне может понадобиться больше информации в файле p2.inf, но я не уверен, что, может быть, что-то вроде пространства имен, имени и диапазона, но я могунайти хороший практический пример.

2) В методе checkForUpdates мне может понадобиться что-то сделать с профилями, чтобы изменить обновляемые устанавливаемые модули.Опять же, я нашел только комментарии, намекающие на это, а не пример кода, который показывает, как.

Любые советы или идеи очень ценятся здесь, это отнимает много времени.

Ответы [ 3 ]

2 голосов
/ 12 октября 2010

Посмотрите на этот код.Перестройте продукт с новой версией продукта и попробуйте настроить 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) {
}
}
});
1 голос
/ 15 октября 2010

@ user473284 в ответ были некоторые предложения, которые я использовал, но я не знаю, были ли они определенными требованиями

1) использование локального веб-сервера вместо попытки указать файл 2) Увеличение версии продуктаи используя хранилище обновлений, сгенерированное мастером экспорта продукта.

Я так и не нашел реализацию метода getUpdate, на которую ссылается пример кода, поэтому я не смог использовать фрагмент.

После вышеуказанных изменений я все еще оставался с приложением, не обнаруживающим никаких обновлений при запуске.Отладка показала, что мой репозиторий не показывался в сеансе.Мне пришлось явно добавить URL обновления в код, несмотря на то, что он был в 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

0 голосов
/ 13 августа 2013
  1. Веб-сервер не является обязательным, вы можете получать обновления с расположением файла.
  2. Также необходимо изменить версию продукта.
  3. Вы не можете обновить те функции с помощью Update Site Project, которые экспортируются вместе с продуктом, однако вы можете сделать это, взломав экспортированный продукт.
  4. Если вы добавите некоторые другие функции с опцией (Установить новое программное обеспечение), вы сможете обновить эти функции с помощью Обновления сборки проекта сайта.

Надеюсь, это будет полезно. Если вам нужно больше разъяснений, вы можете спросить.

...