Skip to content

navpil/hk2-jersey-quartz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HK2 + Jersey + Quartz on Tomcat sample project

  • Quartz is a scheduler
  • Jersey is a REST implementation
  • HK2 is Jersey native DI framework

Problem: how to create Quartz Jobs managed by HK2?

Solution

This project injects Quartz into the HK2 and thus can create HK2 aware jobs.

Package an application and deploy on Tomcat.

Call

http://localhost:8080/quartzhk2/booksapp/books/

And check that the time is updated with scheduler.

Most of the interesting stuff is written in BooksApplication

Code was taken and adapted from StackOverflow

Getting HK2 beans from non managed scope

This one is not really related to the HK2/Jersey/Quartz, but it was interesting for me how to get hold of managed beans outside the HK2 scope. Why would I need it? Some legacy applications can still be written with servlets and gradually migrated to Jersey. In this case accessing some HK2-managed beans is very desirable.

Getting hold of the injected resource outside HK2 context is not that easy. I demonstrate how to do it with the hack of having a static helper. In this way static context plays the role of an Uber Context, since it's managed by JVM. Since I dislike storing dynamic data in static fields I called this approach a Horrible Hack.

This approach is shown in BooksApplicationWithUberHack. To see that non-managed Servlet (NonManagedOldSchoolServlet) has access to the HK2 bean, call the

POST http://localhost:8080/quartzhk2/booksappwithhack/books/manual-update/

And then call

http://localhost:8080/quartzhk2/nonmanaged/bookshack

Eager Initialization

To eagerly initialize something, in our case - starting a Quartz job one can use several approaches

  • Immediate component
  • Immediate resource
  • ContainerLifecycleListener

Immediate component/resource

The cleanest way is definitely an Immediate component. Inside the binder, bind your component with an @Immediate scope (please note that putting this annotation directly on class did not work).

bindAsContract(BooksQuartzJobExecutor.class).in(Immediate.class);

In order this to work register io.github.navpil.q.common.ImmediateFeature.class. And note the @PostConstruct annotation on BooksQuartzJobExecutor where the job is actually started.

Annotation @Immediate work on resources (such as InitializeUberContextResource). You may inject classes there to do some actions on startup, but scoping beans with Immediate.class is cleaner.

An approach with Immediate Scope is shown in BooksApplicationWithImmediateScope and can be accessed on:

http://localhost:8080/quartzhk2/booksapp-with-immediate/books/

ContainerLifecycleListener

Register an implementation of a ContainerLifecycleListener and in the onStartup method you can do:

ServiceLocator serviceLocator = container.getApplicationHandler()
        .getInjectionManager()
        .getInstance(ServiceLocator.class);

And then do whatever you want, for example:

serviceLocator.getService(BooksQuartzJobExecutor.class).start()

or

UberContextHorribleHack.putServiceLocator(BooksApplication.NAME, serviceLocator);

Demonstrated with BooksApplicationContainerLifecycleListener used in BooksApplication, accessed on:

http://localhost:8080/quartzhk2/booksapp/books/

Some links

About

HK2 + Jersey + Quartz on Tomcat sample project

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages