This app does not have an automated migration path

We have updated to the JCMA 1.5.4 recently and now we cannot perform app data migrations. Our app is not recognised as having an automated migration path. This is blocking our JCMA integration work.

Hi @NikolaNedoklanov ,

I’m not a Cloud Migrations expert, but I’ll bring this to the attention of the team. Hopefully they’ll get back to you quickly.

Regards,
Dugald

Hello @NikolaNedoklanov

It is likely that the property cloudMigrationAssistantCompatibility is missing in your “migration info” on Atlassian Marketplace.

You can check the data we have through the URL https://marketplace.atlassian.com/rest/2/addons/YOUR-SERVER-APP-KEY/migration

If that is really missing, you can update it via this endpoint: https://developer.atlassian.com/platform/marketplace/rest/v2/api-group-migrations/#api-addons-addonkey-migration-put

Regards,

Andre

Hi @AndreRosot ,

I am currently developing Jira DC to Cloud (forge) migration.

I ran into a similar problem. The app does not show up in the Migration Assistant.

I run Jira 10.7 and JCMA 1.12.50.

My App data is:

https://marketplace.atlassian.com/rest/2/addons/jiracustomfieldeditorplugin/migration

What is missing?

Maybe the ForgeMigrationListener is not exported as service correctly? I did only find spring scanner examples, but my app is on Java Config, so I tried:

  @Bean
  public ForgeMigrationListener initForgeMigrationListener() {
    return new ForgeMigrationListener();
  }

  @SuppressWarnings("rawtypes") // ServiceRegistration is used as a raw type in the exportOsgiService method
  @Bean
  public FactoryBean<ServiceRegistration> exportBarService(
    final ForgeMigrationListener forgeMigrationListener) {
    ExportOptions options = ExportOptions.as(DiscoverableForgeListener.class);
    return exportOsgiService(forgeMigrationListener, options);
  } 

I also opened ECOHELP-108657 with some other questions.

Would be great if you could point me in the right direction, thanks.

Bernhard

Hi @clouless,

I have in my code

    @Bean
    public FactoryBean<ServiceRegistration> discoverableListener(DiscoverableListener discoverableListener) {
        return exportOsgiService(discoverableListener, ExportOptions.as(DiscoverableListener.class));
    }

which is the Java Configuration way to do it. I’m not explicitly creating the DiscoverableListener object the way you’re doing it.

I’ve put a comment in the ECOHELP-108657 ticket for when it gets picked up.

James.

1 Like

Hi @jrichards

Thanks,

I needed to declare it as bean because it has dependencies. I have changed it to:

  @Bean
  public DiscoverableForgeListener initForgeMigrationListener(
    ClusterLockService clusterLockService,
    EventLogService eventLogService,
    ForgeCloudMigrationService forgeCloudMigrationService) {
    return new ForgeMigrationListener(clusterLockService, eventLogService, forgeCloudMigrationService);
  }

  @SuppressWarnings("rawtypes") // ServiceRegistration is used as a raw type in the exportOsgiService method
  @Bean
  public FactoryBean<ServiceRegistration> exportBarService(
    final DiscoverableForgeListener forgeMigrationListener) {
    ExportOptions options = ExportOptions.as(DiscoverableForgeListener.class);
    return exportOsgiService(forgeMigrationListener, options);
  }

:green_square: Now I see logs of my listener :slight_smile: Thanks a lot:

2026-01-28 08:58:10,844+0000 Caesium-1-4 ERROR ServiceRunner     [i.c.c.editor.migration.ForgeMigrationListener] MIGRATION DATA: {"contextId": {mri:v1:mig:jira/classic:customFieldConfigScheme:10301}},{"fieldId": {mri:v1:mig:jira/classic:customFieldConfigScheme:10301}},{"userId": {mri:v1:mig:jira/classic:customFieldConfigScheme:10301}}

1 Like