jakartaee / batch

The Jakarta Batch project produces the Batch Specification and API.
https://projects.eclipse.org/projects/ee4j.batch
Apache License 2.0
13 stars 17 forks source link

Loading a batch artifact as a CDI Bean by bean name via @Producer in some other bean class #199

Open scottkurz opened 2 years ago

scottkurz commented 2 years ago

Obviously we didn't get to this for 2.1 / EE 10 but a follow-up item possibly if we wish or need to go further with CDI integration:

For a JSL reference:

<batchlet ref="SB">

where the Bean is produced via a producer like:

@Dependent
public class BatchletProducer {

    @Produces
    @Dependent
    @Named("SB")
    public SleepyBatchlet getSleepyBatchlet(JobContext jc) {
        return new SleepyBatchlet(jc);
    }

I would say we have a grey area of the spec.

If we look at the 'jbatch' impl: https://github.com/WASdev/standards.jsr352.jbatch/blob/5889691d72d1c6f760c1d56380dd460b0a17833c/com.ibm.jbatch.container/src/main/java/com/ibm/jbatch/container/services/impl/CDIBatchArtifactFactoryImpl.java#L80-L81

we can see a problem. The "bean class" is the class of the producer here, so the getReference call is going to give us an instance of the producer class, not necessarily the batch artifact class we want.

(I stumbled across essentially the same issue here: https://github.com/OpenLiberty/open-liberty/issues/7995)

It would seem to fix this we would need to know which type we were trying to load, e.g. for a Batchlet do e.g.:

bm.getReference(bean, jakarta.batch.api.Batchlet.class, bm.createCreationalContext(bean))

Since JSL elements don't map 1-1 to batch artifact types (because of how the 'listeners' complicate things), this isn't quite trivial. I would guess that it's solvable if we care enough.

As another data point I tried a similar test in BatchEE which looks to me like it has the exact same code, essentially:

https://github.com/apache/geronimo-batchee/blob/6436f8301e4e7473c79b9570a2103c28b3d90482/jbatch/src/main/java/org/apache/batchee/container/services/factory/CDIBatchArtifactFactory.java#L39-L46

However, I was very surprised to get an instance back from the OpenWebBeans BeanManager of my Batchlet type ! Not sure what to make of that. Now I'm wondering if I did the test correctly (https://github.com/scottkurz/geronimo-batchee/tree/illustrate-issue-199).

rmannibucau commented 2 years ago

Hi Scott,

I think it can be done just by filtering bean.getTypes() and keeping only jakarta.batch types and using the returned type (common subclass of all jakarta types in types if exists) instead of bean class. Think it worked for openwebbeans cause the impl has a hack for producers where it uses for the proxy (getBeanClass()) the right type.