0

I am desperately trying to execute a background task in a JEE 8 application running on Tomcat 7.
I want the user to send a request (through a Jersey REST API) and to receive immediately a response whilst the server process a long task.

I've read tones of articles, but none seems to do the trick right...

Here is what I've got so far

public abstract class AbstractService<T extends Entity> {

    private final ExecutorService es = Executors.newFixedThreadPool(10);

    @Inject
    private EntityManager em;

    [...]

    public void executeAsync(Entity entity) {
        es.execute(() -> {
           // Do some eavy stuffs on the entity
           em.persist(entity);
        });
    }
}

public class PMyEntityService extends AbstractService<MyEntity> {
[...]
}

That doesn't work because the ExecutorService doesn't preserve the context, so my injection isn't available inside the child Threads.

So I did like that

public abstract class AbstractService<T extends Entity> {

    private final ExecutorService es = Executors.newFixedThreadPool(10);

    @Inject
    private EntityManager em;

    [...]

    public void executeAsync(Entity entity) {
        es.execute(() -> {
           EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
           this.em = emf.createEntityManager();
           // Do some eavy stuffs on the entity
           em.persist(entity);
           emf.close();
        });
    }
}

public class MyEntityService extends AbstractService<MyEntity> {
[...]
}

Which seems to work well at the first sight, but after many tries, it appears that if I start many simultaneous requests, many ExecutorService are creating, leading to many EntityManagerFactory, leading to an overload of connexions to the database.

So I tried to put the ExecutorService as static, which doen't work either.

So I've created a new @ApplicationScoped class with only one static field that is an ExecutorService... the database connection is still overflowed.

I tried to implement some ManagedExecutorService but they are only available in javaee-web-api v6.0 while I'm using v8.0.1

I've tried to implement a WorkManager, didn't work either.

I've put my EntityManagerFactory as static in an @ApplicationScoped class, fail again.
...

Please help !

Florent Descroix
  • 579
  • 4
  • 13
  • The [duplicate] does not answer my question. I do not want schedule tasks. – Florent Descroix Jun 02 '20 at 14:58
  • 1
    You asked how to “execute a background task”. The concepts [there](https://stackoverflow.com/a/48855184/642706) still apply: Write a class implementing the two methods defined in `ServletContextListener`. In the `contextInitialized` method, establish your executor service, cached as a context attribute. Retrieve that executor service via the context attribute when your servlet needs to run a task on a background thread. In the `contextDestroyed` method, shutdown the executor service. – Basil Bourque Jun 02 '20 at 15:24

0 Answers0