0

I followed the rest client guide in Quarkus web site. It works fine. But when registering a global provider using the ServiceLoader pattern, as described in the specification, the CDI beans injection did not work, they are all null. I downloaded the example and simply added the following classes:

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;

import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.core.Response;

@ApplicationScoped
public class MyExceptionMapper implements ResponseExceptionMapper<Exception> {

    @Override
    public Exception toThrowable (Response response) {
        return new Exception();
    }
}
package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.spi.RestClientBuilderListener;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

@ApplicationScoped
public class MyListener implements RestClientBuilderListener {

    @Inject MyExceptionMapper myExceptionMapper;

    @Override
    public void onNewBuilder (RestClientBuilder builder) {
        builder.register(myExceptionMapper);
    }
}

I also added the file META-INF/services/org.eclipse.microprofile.rest.client.spi.RestClientBuilderListener with the content org.acme.rest.client.MyListener. The MyListener onNewBuilder method is invoked, but the injected provider MyExceptionMapper is null. How to register a global provider in Quarkus client?

AmsterdamLuis
  • 341
  • 3
  • 21

1 Answers1

0

Implementation of RestClientBuilderListener are not CDI beans - they are just objects that are created via the normal Java ServiceLoader mechanism when RestClientBuilder is being used.

So if you want to obtain CDI beans when onNewBuilder is called, you can do something like:

CDI.current().select(MyExceptionMapper.class).get()

Furthermore, you need to annotate MyExceptionMapper with @Provider, not @ApplicationScoped.

geoand
  • 60,071
  • 24
  • 172
  • 190
  • I tried that but got No bean found for required type [class org.acme.rest.client.MyExceptionMapper] and qualifiers [ [ ] ] Isn't it supposed to just work because of assuming the Default qualifier? – AmsterdamLuis Apr 11 '20 at 09:48
  • Not even adding the Default annotation and using CDI.current().select(MyExceptionMapper.class, new AnnotationLiteral() {}).get(); did it work. – AmsterdamLuis Apr 11 '20 at 09:52
  • Also, is there a way register the providers globally without using the ServiceLoader mechanism? – AmsterdamLuis Apr 11 '20 at 09:54
  • It only worked when adding both the Provider and ApplicationScoped annotations. Also, the ApplicationScoped annotation is unnecessary on MyListener. The need for the Provider annotation makes no sense for me, though. I have many other beans that I want to inject in MyListener, which are not JAX-RS providers, but CDI will only inject them when they are marked as providers. Why? But I guess this is another topic. – AmsterdamLuis Apr 11 '20 at 10:12
  • That line of code CDI.... is awesome. THX for it! – Robert May 07 '23 at 21:56