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.
CodePudding user response:
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).