quarkiverse/quarkus-jberet

Support @BatchProperty of type Enum

Opened this issue · 7 comments

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 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);
    }

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.

@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?

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

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.