Expand my Community achievements bar.

Submissions are now open for the 2026 Adobe Experience Maker Awards.

Mark Solution

This conversation has been locked due to inactivity. Please create a new post.

SOLVED

How to add shutdown hook in CQ5

Avatar

Former Community Member

Hi there,

There is a case for me: i need to persist application some data before JVM shutdown. So i program as below in OSGI bundle:

protected void activate(ComponentContext ctx) { this.bundleContext = ctx.getBundleContext(); final Set<JobBean> jobs = CreateJobServlet.jobNames; jobs.addAll(getInProgressJob()); shutDownHook(jobs); } private Set<JobBean> getInProgressJob() { return getCustomerService().getInProgressJob(); } private void shutDownHook(final Set<JobBean> jobs) { logger.info("Exec shutDownHook()........."); Runtime.getRuntime().addShutdownHook(new Thread(){ public void run(){ logger.info("Running shutdown hook before JVM complete closed......"); getCustomerService().persisJob(jobs); } }); }

However, the function shutDownHook never enter and work, no any log info in background.

Anyone know how to do that? thanks a lot

 

Brian

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi Brian,

Adding a shutdown o the JVM is not best practice within AEM. Because when the JVM finally shuts down, most (all?) of the bundles have been already stopped. So instead of this shutdown hook I would rather tie it to the stop of a bundle or (preferably) to the deactivate of a service.

btw: When you are dealing with sling jobs, you don't have to deal with persisting the jobs yourself...

kind regards,
Jörg

View solution in original post

8 Replies

Avatar

Correct answer by
Employee Advisor

Hi Brian,

Adding a shutdown o the JVM is not best practice within AEM. Because when the JVM finally shuts down, most (all?) of the bundles have been already stopped. So instead of this shutdown hook I would rather tie it to the stop of a bundle or (preferably) to the deactivate of a service.

btw: When you are dealing with sling jobs, you don't have to deal with persisting the jobs yourself...

kind regards,
Jörg

Avatar

Former Community Member

Yes, i find that log record bundle service can't cast class. See below code:

private CustomerService getCustomerService() { BundleContext ctx = FrameworkUtil.getBundle(this.getClass()) .getBundleContext(); ServiceReference serviceReference = ctx .getServiceReference(CustomerService.class.getName()); return CustomerService.class.cast(ctx.getService(serviceReference)); }

 

As a result,Do you mean to tie this task to the deactivate method as following:

protected void deactivate(ComponentContext ctx) { this.bundleContext = null; getCustomerService().persisJob(jobs); }

thanks a lot.

Avatar

Former Community Member

I did try to use that you suggested, however cannot work and throws the same exception: the OSGI service is nullpointer.

Avatar

Employee Advisor

Which OSGI service is null?

Jörg

Avatar

Former Community Member
private CustomerService getCustomerService() { BundleContext ctx = FrameworkUtil.getBundle(this.getClass()) .getBundleContext(); ServiceReference serviceReference = ctx .getServiceReference(CustomerService.class.getName()); return CustomerService.class.cast(ctx.getService(serviceReference)); }

Avatar

Level 10

Look at this stackoverflow thread:

http://stackoverflow.com/questions/24570288/debug-osgi-component-activation-deactivation-issue

It touches upon some of the concepts here.

Avatar

Level 10

Also  does your OSGi service work when called in other places?

Avatar

Former Community Member

sure, that work except JVM shutdown case.