Search code examples
javagradleannotationsjavabeansquarkus

Using Stateless Beans in Quarkus CDI


I have a library containing services annotated with @Stateless which i am not able to modify. For example something like this:

@Stateless
@Local(MyServiceLocal.class)
@Remote(MyServiceRemote.class)
public class MyServiceBean implements MyServiceLocal

Now i want to use those services in my quarkus application, something simple like:

@QuarkusMain
public class MyMain implements QuarkusApplication {
    
    @Inject
    MyServiceLocal myService;

    @Override
    public int run(String... args) {
        myService.doSomething();
    }
}

... but since they have no bean defining annotation, and i am unable to add some, they are not injected.

From my simple understanding, i could use the quarkus AnnotationsTransformer to replace the @Statless annotation with something like @Dependent. But what i don't understand is, how i could activly achieve this, and there are no examples out there that would hint me in the right direction.

What i have is an AnnotationsTransformer which would be able to do excatly this, but how do i apply it to my application? What i gathered would be, that i need a quarkus-extension, with the AnnotationsTransformer in my deployment subproject. But what would be the content of my runtime subproject? I don't need the transformed annotations in the extension but in my quarkus application.

Since my understanding is that i can't use BuildSteps in my quarkus application directly, i'm stuck.

Maybe someone can hint me in the right direction, on how to achieve something like this.


Solution

  • Wow that was surprisingly easy. @Ladicek answer was the final push for understanding the problem.

    I now have a simple quarkus extension with empty runtime subproject, and deployment subproject containing a single class with:

    @BuildStep
    AutoAddScopeBuildItem autoAddScope() {
        return AutoAddScopeBuildItem.builder().containsAnnotations(DotName.createSimple("javax.ejb.Stateless"))
                .defaultScope(BuiltinScope.DEPENDENT)
                .build();
    }
    

    Deployment has a dependency on runtime, and your project has to have a dependency on runtime. I failed to understand how on earth you could possibly benefit from classes in your deployment project.

    deployment -> runtime <- your project
    

    But since in your runtime extension description the deployment project is referenced, it will be loaded up on build time.