This is an issue when a class implements a credential provider interface and is annotated with a dependency injection scope annotation (such as application-scoped) but is missing the annotation that prevents removal during framework optimization.
In Java with CDI and Quarkus, this specifically refers to classes implementing the CredentialsProvider interface, annotated with
@ApplicationScoped (or other CDI scope annotations), and missing the @Unremovable annotation.
In applications using frameworks with build-time optimization, the dependency injection container performs compile-time analysis to reduce the runtime footprint. During this optimization phase, the container analyzes which components are actually used and may remove components that appear to have no injection points or explicit references.
Custom implementations of service provider interfaces are discovered and used at runtime through the frameworkâs plugin or extension mechanism. However, because these providers are typically not injected directly into other components, the dependency injection container cannot detect their usage during build-time analysis.
Without explicit preservation annotations or configuration, the dependency injection container may incorrectly conclude that the custom service provider component is unused and eliminate it during optimization. This leads to a situation where:
Preservation annotations or configuration directives explicitly instruct the dependency injection container to retain the component during optimization, ensuring it remains available for runtime discovery through the service provider interface mechanism.
When a custom credentials provider implementation lacks annotations that prevent removal during build-time optimization, the dependency injection framework may eliminate the implementation as apparently unused. This results in runtime authentication failures when the application attempts to retrieve credentials from the provider.
The application will build successfully, making the issue particularly difficult to detect during development. The failure only manifests when the credentials provider is actually invoked, which could be:
These runtime failures can cause:
Add the @Unremovable annotation to your custom CredentialsProvider implementation. This annotation must be imported from
io.quarkus.arc.Unremovable and placed alongside your CDI scope annotation (typically @ApplicationScoped).
@ApplicationScoped
public class MyCredentialsProvider implements CredentialsProvider { // Noncompliant
@Override
public Map<String, String> getCredentials(String credentialsProviderName) {
Map<String, String> properties = new HashMap<>();
properties.put(USER_PROPERTY_NAME, "user");
properties.put(PASSWORD_PROPERTY_NAME, "password");
return properties;
}
}
@ApplicationScoped
@Unremovable
public class MyCredentialsProvider implements CredentialsProvider {
@Override
public Map<String, String> getCredentials(String credentialsProviderName) {
Map<String, String> properties = new HashMap<>();
properties.put(USER_PROPERTY_NAME, "user");
properties.put(PASSWORD_PROPERTY_NAME, "password");
return properties;
}
}