Expand my Community achievements bar.

SOLVED

What is the replacement for "com.adobe.granite.license. ProductInfoProvider" API

Avatar

Level 2

As per https://developer.adobe.com/experience-manager/reference-materials/cloud-service/javadoc/com/adobe/g... `com.adobe.granite.license.ProductInfo` API is deprecated.

 

What is the replacement? I just want to get the version number of the AEM in my code. Currently I get it using `ProductInfo.getVersion` method.

 

I currently use the version number to determine if my application is running in AEM cloud service or 6.5.x AEM. Any other Java API which can determine that is also should work for me.

Could somebody suggest an alternate way to get the version number or a way to determine in Java at runtime if its cloud or 6.5.x version of AEM?

 

Thanks
Abhijeet

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @abhinarvekar 

 

With the 'prod' run mode, the configuration applies to both AEMaaCS and AEM. However, if another config with a higher-priority run mode exists, that will take precedence.

  • For AEMaaCS, place the configuration inside the config.prod folder.
  • For AMS, use the config.prod.ams folder for environment-specific configurations.

 

 

 

 



Arun Patidar

View solution in original post

6 Replies

Avatar

Community Advisor

Hi @abhinarvekar 

You could have use the OSGI runmode/config to determine the version.

Example of runmodes - AEM6.5 can have prod and ams(custom) run mode

AEM6.5 - prod.ams

AEMaaCS - prod



Arun Patidar

Avatar

Level 5

hi @abhinarvekar ,

Can you please try com.adobe.granite.license.ProductInfoProvider.

 

Thanks,

Anil

Avatar

Level 6

If possible, I would prefer the solution proposed by Arun regarding the run mode, as we know that AEMasCS does not allow custom run mode values. 

 

Another option could be to retrieve the OSGI bundle version of a specific bundle, which we can be certain has different values across various AEM instances. 

 

Here’s the code to achieve this:

/**
     * Retrieves the version of a specific OSGi bundle based on its symbolic name.
     *
     * @Param symbolicNameOfInterest The symbolic name of the bundle to search for (for example "org.apache.jackrabbit.jackrabbit-api").
     * @Return The version of the bundle as a String, or null otherwise
     */
    private String getBundleVersion( String symbolicNameOfInterest) {
        try {
            BundleContext bundleContext = FrameworkUtil.getBundle(HelloWorldModel.class).getBundleContext();
            Bundle[] bundles = bundleContext.getBundles();
            String version = "";
            for (Bundle b : bundles) {
                String symbolicName = b.getSymbolicName();
                if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(symbolicNameOfInterest, symbolicName)) {
                    version = b.getVersion().toString();
                    break;
                }
            }
            if (StringUtils.isBlank(version)) {
                version = null;
            }
            return version;
        } catch (RuntimeException e) {
            LOGGER.error("Error getting bundle version", e);
            return null;
        }
    }

 

Avatar

Level 2

Thanks for the suggestions.

I still see problems with using either approach

 

1. run modes

As AEM 6.5 can have prod and ams. In case of prod it will be same as AEMaaCS

 

2. Using OSGI bundle versions

I tried the code there are about 600 bundles in each 6.5.x and AEMaaCS

Though version are different in 6.5.x and AEMaaCS. I was not able to find deterministically say that a certain version will only be present in AEMaaCS or 6.5.x

I also thought that I could use these bundles to determine AEMaaCS  as they have cloud in their name
185 = "com.adobe.cq.cdn.cdn-rewriter [195]"
186 = "com.adobe.cq.cloud-config.components [196]"
187 = "com.adobe.cq.cloud-config.core [197]"
188 = "com.adobe.cq.cloud-config.ui [198]"

but they are also present in 6.5.x

Also versions are a bit risky, because in future updates if versions get updated in both it will probably break the logic.

I scanned the entire list of bundles for version numbers, but none of them have, for example something like  "2025.1.19149" for cloud and "6.5.22" for 6.5.x AEM which could have been deterministic.

I was thinking if I can just get the version from About Dialog in AEM and parse the HTML to get the version

`/libs/granite/ui/content/shell/about.html`


It looks like an ugly solution but I could get exactly what I want.

<coral-dialog  class="foundation-toggleable granite-help-about-dialog" variant="info" closable="on">
    <coral-dialog-header>About Adobe Experience Manager</coral-dialog-header>
    <coral-dialog-content class="u-coral-noPadding-vertical">
        
        <p>Adobe Experience Manager 2025.1.19149.20250116T154450Z-241100</p>
       ...
       ... 

    </coral-dialog-content>
</coral-dialog>


I will post the code here if I am successful parsing the HTML

Thanks,
Abhijeet

Avatar

Level 2

This is what I came up with, looks not so good, but works!

 

private String getAEMVersion(ResourceResolver resourceResolver) {
  String aboutPath = "/libs/granite/ui/content/shell/about";
  String aboutHTML = resolveResourceToHtml(resourceResolver, aboutPath);
  return extractVersion(aboutHTML);
}
  
private String resolveResourceToHtml(
    ResourceResolver resourceResolver, String resourcePath) {
  try {
    SlingHttpServletRequestBuilder requestBuilder =
        Builders.newRequestBuilder(
                Objects.requireNonNull(resourceResolver.getResource(resourcePath)))
            .withRequestMethod("GET")
            .withExtension("html");

    HttpServletRequest httpServletRequest = requestBuilder.build();

    SlingHttpServletResponseBuilder responseBuilder = Builders.newResponseBuilder();
    HttpServletResponse httpServletResponse = responseBuilder.build();
    CapturingHttpServletResponseWrapper capturingResponse =
        new CapturingHttpServletResponseWrapper(httpServletResponse);

    slingRequestProcessor.processRequest(httpServletRequest, capturingResponse, resourceResolver);

    return capturingResponse.getCapturedResponse();

  } catch (ServletException | IOException e) {
    logger.error("Something went wrong while resolving resource...", e);
  }

  return "";
}

private String extractVersion(String html) {
  if (html == null || html.isEmpty()) {
    return null;
  }
  String regex = "Adobe Experience Manager\\s+([\\d\\.]+[^<]*)";
  Pattern pattern = Pattern.compile(regex);
  Matcher matcher = pattern.matcher(html);

  if (matcher.find()) {
    String versionString = matcher.group(1).trim();
    return versionString;
  }

  String regex2 = "([\\d\\.]+[^<]*)";
  Pattern pattern2 = Pattern.compile(regex2);
  Matcher matcher2;

  String[] htmlSplit = html.split("<p>");
  for (String line : htmlSplit) {
    if (line.contains("Adobe Experience Manager")) {
      matcher2 = pattern2.matcher(line);
      if (matcher2.find()) {
        return matcher2.group(1).trim();
      }
    }
  }

  return null;
}

 

Thanks,
Abhijeet

Avatar

Correct answer by
Community Advisor

Hi @abhinarvekar 

 

With the 'prod' run mode, the configuration applies to both AEMaaCS and AEM. However, if another config with a higher-priority run mode exists, that will take precedence.

  • For AEMaaCS, place the configuration inside the config.prod folder.
  • For AMS, use the config.prod.ams folder for environment-specific configurations.

 

 

 

 



Arun Patidar