quarkiverse / quarkus-jberet

Quarkus Extension for Batch Applications.
Apache License 2.0
51 stars 23 forks source link

Support @BatchProperty of type Enum #243

Open gquintana opened 1 year ago

gquintana commented 1 year ago

Given a job property defined as an enum named BatchMode

@BatchProperty(name = "batchMode") BatchMode batchMode

I get an injection error

Caused by: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
    [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.mycompany.myapp.batch.BatchMode and qualifiers [@BatchProperty(name = "batchMode")]
    - java member: com.mycompany.myapp.batch.user.UserDqlReader():batchMode
    - declared on CLASS bean [types=[jakarta.batch.api.chunk.ItemReader, com.mycompany.myapp.batch.DqlItemReader<com.mycompany.myapp.model.User>, jakarta.batch.api.chunk.AbstractItemReader, com.mycompany.myapp.batch.user.UserDqlReader, java.lang.Object], qualifiers=[@Default, @Any, @Named("UserDqlReader")], target=com.mycompany.myapp.batch.user.UserDqlReader]
    at io.quarkus.arc.processor.BeanDeployment.procerrors(BeanDeployment.java:1435)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:310)
    at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:155)
    at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:469)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:864)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:282)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
    at java.base/java.lang.Thread.run(Thread.java:833)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.mycompany.myapp.batch.BatchMode and qualifiers [@BatchProperty(name = "batchMode")]
    - java member: com.mycompany.myapp.batch.user.UserDqlReader():batchMode
    - declared on CLASS bean [types=[jakarta.batch.api.chunk.ItemReader, com.mycompany.myapp.batch.DqlItemReader<com.mycompany.myapp.model.User>, jakarta.batch.api.chunk.AbstractItemReader, com.mycompany.myapp.batch.user.UserDqlReader, java.lang.Object], qualifiers=[@Default, @Any, @Named("UserDqlReader")], target=com.mycompany.myapp.batch.user.UserDqlReader]
    at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:477)
    at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:624)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:298)
    ... 13 more

Even if it's not described in the Jakarta Batch 2.1 Spec, there is a ValueConverter in JBeret which should be able to do the String to Enum conversion: https://github.com/jberet/jsr352/blob/main/jberet-core/src/main/java/org/jberet/creation/ValueConverter.java

luca-bassoricci commented 1 year ago

I think this has to be a Jberet job: https://github.com/jberet/jsr352/blob/main/jberet-core/src/main/java/org/jberet/creation/BatchBeanProducer.java is missing Enum injection

gquintana commented 1 year ago

@luca-bassoricci do you mean it could be as simple as adding a method:

    @Produces @BatchProperty
    public Enum getEnum(final InjectionPoint injectionPoint) {
        return getProperty(injectionPoint, Enum.class);
    }
radcortez commented 1 year ago

Yes, this is not an issue with this extension directly, but a missing thing in JBeret.

I'm not sure if a simple Enum producer is enough. I don't think CDI can match java.lang.Enum to a specific enum type. Most likely, this requires a BeanProducer.

luca-bassoricci commented 10 months ago

@radcortez Collecting all injected enum annotated with @BatchProperty during build phase and create a synthetic EnumBeanProducer with a specific producer for every collected enum types should solve the problem?

radcortez commented 10 months ago

Correct, but shouldn't this be fixed directly in JBeret?

luca-bassoricci commented 10 months ago

Absolutely; I thought adding enum support as a contribute to jberet, but my competencies in CDI are so scarce but - for now - I drop the idea.

luca-bassoricci commented 4 months ago

https://github.com/jberet/jsr352/issues/548