AEM — JMX Solution to delete packages programmatically

Pradeep Moolemane
Nggawe Nirman Tech Blog
3 min readNov 7, 2020

Package — A package is a zip file holding repository content in the form of a file system serialization that enables easy to use and edit files & folders.

Package also contains vault information including filter definition, import configuration. Additional content properties can be included in the package such as description, a visual image or an icon.

Imp: Packages are current version of content repository at the time package built.

Following action can perform on/with packages.

Create package, preview package content, build package, view package information, view package content, modify package definition, rebuild package, download/upload packages etc.

Create package:

Go to Package manager -> create package -> provide information — Package name, version, group. Minimum information package name must be given to create package. And by default, packages created under “my_packages” group.

Once package create, we can view the package information by clicking edit option.

Delete package: If we do not manage packages, packages consume lot of space on AEM instance. Its always good to delete unwanted packages from AEM instance and free up the space.

We will discuss about JMX solution to delete packages where JMX is java technology that provides tools for managing and monitoring application, system objects and devices.

Why JMX?

1) Easy solution and intuitive

2) JMX operation can be performed only by the user with access to system console on AEM — this ensures no accidental delete operation

3) Delete operation can be done only when necessary

Steps to delete packages:

1) Create an interface for JMX MBean

@Description(“DeleteAEM Packages MBean used to delete unwanted packages from group my_package group”)

public interface DeleteAEMPackagesMBean {

@Description(“DeleteAEM Packages MBean used to delete unwanted packages from group my_package group”)

String deletePackages();

}

2) Create an implementation class implementing DeleteAEMPackageMBean interface

@Component(service = DeleteAEMPackagesMBean.class, immediate = true, property = {

“jmx.objectname=au.com.example.core.services.impl:type=Delete AEM Packages” })

public class DeleteAEMPackagesMBeanImpl extends AnnotatedStandardMBean implements DeleteAEMPackagesMBean {

private static final Logger LOGGER = LoggerFactory.getLogger(DeleteAEMPackagesMBeanImpl.class);

public DeleteAEMPackagesMBeanImpl() throws NotCompliantMBeanException {

super(DeleteAEMPackagesMBean.class); }

@Override

public String deletePackages() { //implementation

}

}

AnnotatedStandardMBean provides JMX metadata through annotations.

3) Package API for working with packages

Get reference to Packaging from vault packaging implementation that gives access package manager

@Reference

Packaging packaging;

Get JcrPackageManager reference using packaging object by passing session.

JcrPackageManager jcrPackMgr = packaging.getPackageManager(

session.getServiceResourceResolver(ApplicationConstants.SubService.BREVILLESERVICE)

.adaptTo(Session.class));

From jcrPackMgr object, get the list of package with filter group/build etc.

List<JcrPackage> jrcPackages = jcrPackMgr.listPackages(“my_packages”, true);

Iterate over List and have custom implementation logic to filter the packages.

4) Delete package

Once you get the desired package to delete based on custom logic, below line can be used to delete the package.

jcrPackMgr.remove(jcrPackage);

@Override

public String deletePackages() {

LOGGER.error(“deletePackages method has been invoked”);

try {

JcrPackageManager jcrPackMgr = packaging.getPackageManager(

session.getServiceResourceResolver(ApplicationConstants.SubService.BREVILLESERVICE)

.adaptTo(Session.class));

LOGGER.error(“JcrPackage Mgr object = {} “, jcrPackMgr);

List<JcrPackage> jrcPackages = jcrPackMgr.listPackages(“my_packages”, true);

LOGGER.error(“Packages list size = {} “, jrcPackages.size());

double totalSizeMB = 0;

for (Iterator iterator = jrcPackages.iterator(); iterator.hasNext();) {

JcrPackage jcrPackage = (JcrPackage) iterator.next();

PackageId[] packageIdArr = jcrPackage.getResolvedDependencies();

LOGGER.info(“Dependent packages = {}”, packageIdArr.length);

// dont delete if this depends on some other package

if (packageIdArr.length == 0 && jcrPackage.getSize() > 0) {

LOGGER.info(“Package size = {} “, jcrPackage.getSize());

jcrPackage.getSize();

double kbs = (jcrPackage.getSize() / 1000d);

totalSizeMB += kbs / 1000;

JcrPackageDefinition packDefinition = jcrPackage.getDefinition();

if (packDefinition != null) {

String nodeName = packDefinition.get(“name”);

if(nodeName != null && nodeName.equals(“breville-commerce-nodes”)) {

jcrPackMgr.remove(jcrPackage);

}

}

}

}

LOGGER.info(“Packages total size in MB = {}”, totalSizeMB);

} catch (LoginException e) {

LOGGER.error(“Error while getting session {} “, e.getMessage());

} catch (RepositoryException e) {

LOGGER.error(“RepositoryException occured while getting packages {} “, e.getMessage());

}

return “Successfully deleted my_packages”;

}

Run delete operation from JMX console.

JMX console:

Invoke operation:

Success message:

--

--