0

I have a very curious dependency injection resolve error during compile time. I have a property in application.properties, which i inject via the @ConfigProperty annotation in a Quarkus project. I have multiple @ConfigProperty injections in the project, none of which cause an issue except one. When i compile the project, i get the following maven error:

javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.lang.String and qualifiers [@Default]

To give more details, it states specifically which member is the issue:

java member: com.webscraper.bot.base.builder.ConfigWebScraperBuilder():webScraperClassName [ERROR] - declared on CLASS bean [types=[com.webscraper.bot.base.builder.ConfigWebScraperBuilder, java.lang.Object], qualifiers=[@Default, @Any], target=com.webscraper.bot.base.builder.ConfigWebScraperBuilder]

Usually with an error like this, i would look for missing @ApplicationScoped annotations or such indicating that injected dependency cannot be resolved. However, what is weird here is that it is saying that java.lang.String is the unsatisfied dependency - how is that possible? As i said before, i use the @ConfigProperty annotiation in other places perfectly fine for other basic Java data class types like Long etc. (e.g. for "bot.id" property).

Here is the application.properties:

bot.id = 1
bot.webscraper.className = Test

Here is the class where the error is raised from (i made the webScraperClassName field not private final because i wanted to see whether this is causing injection issues here):

@ApplicationScoped
public class ConfigWebScraperBuilder {
    @ConfigProperty(name = "bot.webscraper.className")
    String webScraperClassName;

    public ConfigWebScraperBuilder(String webScraperClassName) {
        this.webScraperClassName = webScraperClassName;
    }

    public WebScraper buildWebScraperFromConfig() throws Exception {
        Class<?> clazz = Class.forName(webScraperClassName);
        Constructor<?> constructor = clazz.getConstructor(ParserAdapter.class);
        return (WebScraper) constructor.newInstance(new Object[] { new ParserAdapter() });
    }
}

Edit: The @ConfigProperty annotation is imported from org.eclipse.microprofile.config.inject.ConfigProperty and the same one used in other locations where the injection works perfectly fine.

1
  • In my case I was not injecting a property (@ConfigProperty) but creating a new instance, so at the end I just needed to create a no-args constructor, in order to have two constructors at the end. The other option was to create a Producer but that seems more complex. Commented Jun 2, 2023 at 20:36

1 Answer 1

3

I think this is caused by Quarkus (or ArC, actually) finding a single constructor and hence treating that constructor as the bean constructor. All parameters of the bean constructor are injection points, so ArC tries to resolve a bean of type String with the @Default qualifier (which is implied because no other qualifier is present).

If you want the container to inject a config property into the parameter, add the @ConfigProperty qualifier annotation to the parameter. If you don't want the container to inject anything into a constructor, declare a zero-parameter constructor (and mark it @Inject if you want to keep the other constructor).

Sign up to request clarification or add additional context in comments.

1 Comment

You are 100% correct, i forgot to came back to post my own solution (apologies). I came back with a fresh pair of eyes this morning and instantly noticed that the container wouldn't know what to inject for a string by itself. Thank you for posting this, as others may stumble across this issue while not noticing this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.