1
votes

I have some trouble injecting a config class into a service class in Quarkus. I have this config class:

import io.quarkus.arc.config.ConfigProperties;

@ConfigProperties(prefix = "database")
public class TestConfig {
    public String url = "http://localhost:8086";
    public String user;
    public String password;
    public String name;
    public ColumnConfig column;
    public int pagination = 1000;


    public static class ColumnConfig {
        public String value = "value";
        public String device;
        public String type;
    }
}

When I use it my resource class it's fine

@Path("/measurements")
@Tag(name = "measurements")
@Produces(MediaType.APPLICATION_JSON)
public class MeasurementResource {

    @Inject
    MeasurementService delegate;

    @Inject
    TestConfig config;

    @GET
    @Path("/last")
    public MeasurementResult getLastMeasurements() {
        System.out.println(config.url); //works
        //...

    }

But I actually want to use it the MeasurementService class. But it doesn't work there.

@ApplicationScoped
public class MeasurementService {
    
    private static InfluxDBMapper mapper;
    
    @Inject
    TestConfig config;

    public MeasurementService() {
        System.out.println(config.url);     // exception here
        System.out.println(config.password);
        System.out.println(config.column.tenant);
        config = DatabaseConfig.getInstance();
        InfluxDB influxDB = InfluxDBFactory.connect(config.url, config.user, config.password);
        //...

I get an exception saying that MeasurementService can't be injected because of a NullPointerException. The exception happens when the print command is executed. I marked it in the snippet above.

org.jboss.resteasy.spi.UnhandledException: java.lang.RuntimeException: Error injecting de.*.services.MeasurementService de.*.resources.MeasurementResource.delegate
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:381)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
    at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:136)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:40)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:97)
    at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:231)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at java.base/java.lang.Thread.run(Thread.java:834)
    at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: java.lang.RuntimeException: Error injecting de.*.services.MeasurementService de.*.resources.MeasurementResource.delegate
    at de.*.resources.MeasurementResource_Bean.create(MeasurementResource_Bean.zig:171)
    at de.*.resources.MeasurementResource_Bean.create(MeasurementResource_Bean.zig:194)
    at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96)
    at io.quarkus.arc.impl.AbstractSharedContext.access$000(AbstractSharedContext.java:14)
    at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29)
    at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26)
    at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
    at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
    at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26)
    at de.*.resources.MeasurementResource_Bean.get(MeasurementResource_Bean.zig:226)
    at de.*.resources.MeasurementResource_Bean.get(MeasurementResource_Bean.zig:242)
    at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:435)
    at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:448)
    at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:271)
    at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:268)
    at io.quarkus.arc.runtime.BeanContainerImpl$1.create(BeanContainerImpl.java:35)
    at io.quarkus.resteasy.common.runtime.QuarkusConstructorInjector.construct(QuarkusConstructorInjector.java:54)
    at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.createResource(POJOResourceFactory.java:71)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:386)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
    ... 20 more
Caused by: java.lang.NullPointerException
    at de.*.services.MeasurementService.<init>(MeasurementService.java:43)
    at de.*.MeasurementService_ClientProxy.<init>(MeasurementService_ClientProxy.zig:24)
    at de.*.MeasurementService_Bean.proxy(MeasurementService_Bean.zig:40)
    at de.*.MeasurementService_Bean.get(MeasurementService_Bean.zig:221)
    at de.*.services.MeasurementService_Bean.get(MeasurementService_Bean.zig:237)
    at de.*.resources.MeasurementResource_Bean.create(MeasurementResource_Bean.zig:154)
    ... 40 more

I guess there is a problem because I try to inject a class into a class that also is injected somewhere else, but I'm not sure and hope there is a solution to this.

Thank you.

EDIT:

The solution is to inject the class in the constructor like this:

@ApplicationScoped
public class MeasurementService {
    
    private static InfluxDBMapper mapper;
    
    @Inject
    public MeasurementService(TestConfig config) {

Thanks to Luca for the idea.

1

1 Answers

3
votes

I'm not 100% sure about that,but properties are binded after object construction; this is the reason why TestConfig config is null.
Use constructor injection instead: @Inject public MeasurementService(TestConfig config)