1

I'm working on a Service class which is annotated with @RequestScope, the problem is that there is one method which takes too long time to proceed and I'm wondering if it's possible to create new Thread in which part of the code will be executed.

I've tried using ManagedExecutorService, CompletableFuture.runAsync(()) and a simple Thread, but none of them seems to work?

@RequestScoped
public class OfferService 

And the method:

  public List<DTO> createLocation(List<DTO> locationAdressDTOS) {
        List<DTO> lokationLookupList ;

        locationLookupList = offerDao.createMarktlokation(DTOS.get(0).getOfferNo(), DTOS);

        DTOS.forEach(malo -> {
            if (BooleanUtils.isTrue(malo.isShouldUploadHistoricalData()) && malo.getProcessId() != null) {
                callHistoricalDataUpload(malo.getOfferNo(), malo.getProcessId());
            }
        });
        return lokationLookupList;
    }

And I want the if part to be run asynchronous? //

 callHistoricalDataUpload(malo.getOfferNo(), malo.getProcessId());

I believe the reason that it's not working is because the class is annotated with @RequestScope and after it returns the response is being destroyed and it's context too? When I try to simply create a new Thread:

2019-05-23 14:45:31,934 ERROR [stderr] (Thread-225) Exception in thread "Thread-225" org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped

What I have tried:

CompletableFuture.runAsync(() -> {
            try {
                this.uploadHistoricalData(offerNo, processId);
            } catch (DatatypeConfigurationException | ParseException e) {
                logger.severe(e.getMessage());
            }
        });


        managedExecutorService.execute(() -> {
            try {
                this.uploadHistoricalData(offerNo, processId);

            } catch (DatatypeConfigurationException | ParseException e) {
                logger.severe(e.getMessage());
            }
        });


        new Thread((() -> {
            try {

                this.uploadHistoricalData(offerNo, processId);

            } catch (DatatypeConfigurationException | ParseException e) {
                logger.severe(e.getMessage());
            }
        })).start();

None of that worked

dnny
  • 116
  • 1
  • 7

1 Answers1

-1

It seems that your problem is that same as this other question on StackOverflow.

It's because the request is tied to the server thread processing the request. When you switch threads, there is no longer access to that request context.

You might not need the @RequestScoped annotation.

Álex Fogaça
  • 84
  • 1
  • 5
  • Unfortunately I cannot remove this annotation. Is it possible to propagate the request context to the new thread? – dnny May 23 '19 at 14:36
  • It is. You may collect the data you need before and then use it on your asynchronous call. – Álex Fogaça May 23 '19 at 14:41
  • There is a solution available on this [thread about propagating the request scope to an asynchronous task](https://stackoverflow.com/questions/23732089/how-to-enable-request-scope-in-async-task-executor), but it's a bit much depending on your situation. – Álex Fogaça May 23 '19 at 14:43
  • Thats a spring dependent solution – dnny May 23 '19 at 14:54
  • Sorry, my mistake. I've found this [other solution](https://stackoverflow.com/questions/34815608/local-thread-linked-with-requestscope) and it seems concise. – Álex Fogaça May 23 '19 at 16:31
  • Thanks! that looks viable, I will give it a try and reply if it works! :) – dnny May 24 '19 at 22:57