0

First time using Quarkus, it's probably a noob question but I have no idea how to resolve. I'm trying to set up an endpoint which should run a Genetic Algorithm (made with Jenetics) and return the result. This is the endpoint definition:

@Path("/items")
public class ItemResource {

    @Inject
    ItemService service;

    @GET
    public List<Item> getItems() {
        return service.getItems();
    }

}

The endpoint demands the execution to the service class below:

@ApplicationScoped
public class ItemService {

    @Inject
    ItemMapper mapper;

    @Transactional
    public List<Item> getItems() {
        int numOfItems = Math.toIntExact(Item.count());
        IntegerChromosome chromosome = IntegerChromosome.of(0, numOfItems - 1, 14);
        Factory<Genotype<IntegerGene>> factory = Genotype.of(chromosome);
        Engine<IntegerGene, Double> engine = Engine
                .builder(this::fitnessFunction, factory)
                .build();
        Genotype<IntegerGene> result = engine.stream()
                .limit(100)
                .collect(EvolutionResult.toBestGenotype());
        return mapper.toItems(result);
    }

}

and finally this is the mapper class:

@ApplicationScoped
public class ItemMapper {

    public List<Item> toItems(Genotype<IntegerGene> genotype) {
        List<Item> items = Item.listAll();
        return genotype.chromosome().stream()
                .map(IntegerGene::intValue)
                .map(items::get)
                .collect(Collectors.toList());
    }

}

When I run the code above, I get the following exception:

Error handling 0d80baf3-12da-49ec-b8d0-e48472c801c9-1, org.jboss.resteasy.spi.UnhandledException: java.util.concurrent.CancellationException: javax.enterprise.context.ContextNotActiveException

The code runs flawlessly in a standard Java application, but not in a web service. Any idea?


Here you can find the stack trace.

Andrea
  • 675
  • 1
  • 13
  • 34
  • Does it work if you move `@Transactional` to `ItemResource`? – geoand Mar 18 '21 at 06:30
  • No, it throws the same exception. – Andrea Mar 18 '21 at 08:09
  • Can you add the stack trace? Does `Item` contain DB access code? Is any part of the calculations (either in `Item` or in Jenetics) asynchronous - i.e. on another thread? – Nikos Paraskevopoulos Mar 18 '21 at 10:13
  • By default, Jenetics uses the `ForkJoinPool.defaultPool()` for evaluating the fitness values concurrently. If this is the problem, you can explicitly set the used `Executor` when building the engine. And yes, a full stack-trace would be usefull. – Franz Wilhelmstötter Mar 18 '21 at 16:12
  • Is there a way for Jenetics to be configured with a specific thread pool? – geoand Mar 18 '21 at 17:43
  • @NikosParaskevopoulos Item is a [PanacheEntity](https://quarkus.io/guides/hibernate-orm-panache) so yes, it definitely contains DB access code. Specifically, I'm using the two static methods `count()` and `listAll()` – Andrea Mar 19 '21 at 15:41
  • @FranzWilhelmstötter I've just added the stack trace, have a look at the updated question – Andrea Mar 19 '21 at 15:43

1 Answers1

0

You can try to set a different execution service.

final Executor executor = Executors.newFixedThreadPool(10);
final Engine<EnumGene<WayPoint>, Double> engine = Engine.builder(...)
    .executor(executor)
    .build();
  • You will most probably receive the same `ContextNotActiveException` with a hand-crafted executor. If so, inject the `ManagedExecutorService` as `@Resource ManagedExecutorService managedExecutor` and use that. – Nikos Paraskevopoulos Mar 18 '21 at 21:38
  • I've indeed received the same exception by setting `Executors.newFixedThreadPool(10)` as executor. I'm willing to try `@Resource ManagedExecutorService managedExecutor` but I can't find this class, should I create it somehow? – Andrea Mar 19 '21 at 15:46
  • Hi @Andrea, it's `javax.enterprise.concurrent.ManagedExecutorService` and `javax.annotation.Resource`. I am not sure if this works for Quarkus, although it does work for traditional JEE. If it doesn't, you can try 2 things: (1) `@Inject ManagedExecutorService` instead of `@Resource ...` and (2) use MicroProfile's `ManagedExecutor` as described [here](https://quarkus.io/guides/context-propagation) and Andy's answer to [this question](https://stackoverflow.com/questions/59442653/howto-obtain-a-threadfactory-in-quarkus). – Nikos Paraskevopoulos Mar 19 '21 at 16:42
  • @NikosParaskevopoulos Apparently `ManagedExecutorService` doesn't works in Quarkus, so I tried with `@Inject ManagedExecutor executor`. I get the same exception, but with a [different stack trace](https://pastebin.com/SVF9VaXB) – Andrea Mar 19 '21 at 17:11