Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hazelcast threads prevent TomEE from stopping

Context

We want to use Hazelcast as our JCache implementation inside TomEE. As we don't need insane performance, at the moment, we want to run the Hazelcast node as part of our application.

We use Hazelcast 3.7 and TomEE 7.0.1.

Problem

When stopping TomEE, it complains about WARNING - The web application [APPLICATION_NAME] appears to have started a thread named [SOMENAME] but has failed to stop it. This is very likely to create a memory leak. several times and the VM will not halt normally but keep running.

The workaround obviously is to kill the process as soon as it looks idle. Needless to say that this is driving our developers and dev ops crazy.

Separate Hazelcast node

To rule out the possibility that the problems arise from the Hazelcast node being run inside TomEE, I tried to start a stand alone Hazelcast node and changed our application to only use the Hazelcast client to connect to said node. The behaviour stayed the same. As far as I can tell from several web searches, the Hazelcast client starts several threads as well, to communicate with the server nodes.

No duplicate of Hazelcast prevents the JVM from terminating

This question is not a duplicate of Hazelcast prevents the JVM from terminating as we totally rely on Hazelcasts JCache implementation. We do not access the Hazelcast instance directly and thus, we cannot call shutDownAll().

Test case

I've created a small test case on GitHub to reproduce the problem.

Questions

  • Can we use Hazelcast as JCache backend in a Java EE application?
  • What do we have to do to allow the application to stop normally?
  • Can we also run the Hazelcast node as part of our application? If not: Why is this a bad idea?
like image 334
Schroenser Avatar asked Aug 22 '16 13:08

Schroenser


2 Answers

Hazelcast uses its own threads and they are not always daemon, you can ensure you shutdown your hazelcast instance (client or node) through a producer like the one in https://issues.apache.org/jira/browse/TOMEE-1723

Until hazelcast fixes the lifecycle of its instance through a CDI extension it is likely the cleanest you can do.

Note: this is also doable using tomee internal server API to start the instance earlier but not needed for most cases

like image 115
Romain Manni-Bucau Avatar answered Oct 20 '22 14:10

Romain Manni-Bucau


Solution

rmannibucau's answer pointed me to the right direction.

I added a bean that @Observes @Destroyed(ApplicationScoped.class) and calls Caching.getCachingProvider().close(). This in turn shuts down the underlying Hazelcast instance.

This solution also avoids direct interaction with Hazelcast classes. The dependency can remain limited to the runtime scope.

I added a branch to the test case with this solution.

like image 44
Schroenser Avatar answered Oct 20 '22 14:10

Schroenser