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
Solved! Go to Solution.
Views
Replies
Total Likes
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.
config.prod
folder.config.prod.ams
folder for environment-specific configurations.
Views
Replies
Total Likes
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
Views
Replies
Total Likes
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;
}
}
Views
Replies
Total Likes
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
Views
Replies
Total Likes
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
Views
Replies
Total Likes
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.
config.prod
folder.config.prod.ams
folder for environment-specific configurations.
Views
Replies
Total Likes