Core dependency injection interfaces and components for the Micronaut Framework
—
Micronaut Inject provides a comprehensive exception hierarchy for handling dependency injection errors, bean resolution failures, and configuration issues. Understanding these exceptions is crucial for proper error handling and debugging.
Base exception for all bean context related errors.
public class BeanContextException extends RuntimeException {
public BeanContextException(String message);
public BeanContextException(String message, Throwable cause);
}Thrown when a required bean cannot be found in the context.
public class NoSuchBeanException extends BeanContextException {
public NoSuchBeanException(Class<?> beanType);
public NoSuchBeanException(Class<?> beanType, Qualifier<?> qualifier);
public NoSuchBeanException(String message);
public Class<?> getBeanType();
public Qualifier<?> getQualifier();
}Thrown when multiple beans match a type but only one is expected.
public class NonUniqueBeanException extends BeanContextException {
public NonUniqueBeanException(Class<?> beanType, Collection<BeanDefinition<?>> possibleCandidates);
public Class<?> getBeanType();
public Collection<BeanDefinition<?>> getPossibleCandidates();
}Thrown when bean instantiation fails.
public class BeanInstantiationException extends BeanContextException {
public BeanInstantiationException(String message);
public BeanInstantiationException(String message, Throwable cause);
public BeanInstantiationException(BeanDefinition<?> beanDefinition, Throwable cause);
public BeanDefinition<?> getBeanDefinition();
}Thrown when dependency injection fails.
public class DependencyInjectionException extends BeanContextException {
public DependencyInjectionException(String message);
public DependencyInjectionException(String message, Throwable cause);
public DependencyInjectionException(BeanDefinition<?> beanDefinition, Argument<?> argument, String message);
public BeanDefinition<?> getBeanDefinition();
public Argument<?> getArgument();
}Thrown when configuration-related errors occur.
public class ConfigurationException extends RuntimeException {
public ConfigurationException(String message);
public ConfigurationException(String message, Throwable cause);
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.NoSuchBeanException;
public class MissingBeanExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
try {
// This will throw NoSuchBeanException if UserService is not registered
UserService service = context.getBean(UserService.class);
service.createUser("John");
} catch (NoSuchBeanException e) {
System.err.println("Bean not found: " + e.getBeanType().getSimpleName());
System.err.println("Available alternatives:");
// Try to find similar beans
context.getBeanDefinitions(Object.class).stream()
.filter(def -> def.getBeanType().getSimpleName().contains("Service"))
.forEach(def -> System.err.println(" - " + def.getBeanType().getName()));
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.NonUniqueBeanException;
import io.micronaut.inject.qualifiers.Qualifiers;
// Multiple implementations
@Singleton
public class EmailNotificationService implements NotificationService {
// Email implementation
}
@Singleton
public class SmsNotificationService implements NotificationService {
// SMS implementation
}
public class NonUniqueBeanExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
try {
// This will throw NonUniqueBeanException
NotificationService service = context.getBean(NotificationService.class);
} catch (NonUniqueBeanException e) {
System.err.println("Multiple beans found for: " + e.getBeanType().getSimpleName());
System.err.println("Candidates:");
for (BeanDefinition<?> candidate : e.getPossibleCandidates()) {
System.err.println(" - " + candidate.getBeanType().getName());
}
// Resolve using qualifier
NotificationService emailService = context.getBean(
NotificationService.class,
Qualifiers.byName("email")
);
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.BeanInstantiationException;
@Singleton
public class ProblematicService {
public ProblematicService() {
// This constructor throws an exception
if (System.currentTimeMillis() % 2 == 0) {
throw new RuntimeException("Random initialization failure");
}
}
}
public class InstantiationErrorExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
try {
ProblematicService service = context.getBean(ProblematicService.class);
} catch (BeanInstantiationException e) {
System.err.println("Failed to create bean: " + e.getBeanDefinition().getBeanType());
System.err.println("Cause: " + e.getCause().getMessage());
// Log full stack trace for debugging
e.printStackTrace();
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.DependencyInjectionException;
@Singleton
public class ServiceWithDependency {
@Inject
public ServiceWithDependency(NonExistentService dependency) {
// This will fail because NonExistentService doesn't exist
}
}
public class DependencyInjectionErrorExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
try {
ServiceWithDependency service = context.getBean(ServiceWithDependency.class);
} catch (DependencyInjectionException e) {
System.err.println("Dependency injection failed for: " +
e.getBeanDefinition().getBeanType().getSimpleName());
if (e.getArgument() != null) {
System.err.println("Failed argument: " + e.getArgument().getName() +
" (" + e.getArgument().getType().getSimpleName() + ")");
}
System.err.println("Reason: " + e.getMessage());
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.ConfigurationException;
import io.micronaut.context.env.Environment;
public class ConfigurationErrorExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
Environment env = context.getEnvironment();
try {
// This will throw ConfigurationException if property is missing
String requiredValue = env.getRequiredProperty("required.property", String.class);
} catch (ConfigurationException e) {
System.err.println("Configuration error: " + e.getMessage());
// Show available properties for debugging
System.err.println("Available properties:");
env.getPropertySources().forEach(source -> {
System.err.println(" Source: " + source.getName());
});
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.BeanInstantiationException;
import jakarta.validation.ConstraintViolationException;
@ConfigurationProperties("database")
public class DatabaseConfig {
@NotBlank
private String url;
@Min(1)
@Max(100)
private int maxConnections;
// Getters and setters
}
public class ValidationErrorExample {
public static void main(String[] args) {
// Run without proper configuration
try (ApplicationContext context = ApplicationContext.run()) {
try {
DatabaseConfig config = context.getBean(DatabaseConfig.class);
} catch (BeanInstantiationException e) {
if (e.getCause() instanceof ConstraintViolationException) {
ConstraintViolationException validationError =
(ConstraintViolationException) e.getCause();
System.err.println("Configuration validation failed:");
validationError.getConstraintViolations().forEach(violation -> {
System.err.println(" " + violation.getPropertyPath() +
": " + violation.getMessage());
});
}
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.NoSuchBeanException;
@Singleton
public class ResilientService {
private final NotificationService notificationService;
private final boolean notificationEnabled;
@Inject
public ResilientService(ApplicationContext context) {
// Try to get notification service, fall back to null if not available
NotificationService service = null;
boolean enabled = false;
try {
service = context.getBean(NotificationService.class);
enabled = true;
} catch (NoSuchBeanException e) {
System.warn.println("Notification service not available, continuing without notifications");
}
this.notificationService = service;
this.notificationEnabled = enabled;
}
public void processOrder(Order order) {
// Core processing always works
order.setStatus(OrderStatus.PROCESSED);
// Optional notification
if (notificationEnabled && notificationService != null) {
try {
notificationService.sendOrderConfirmation(order);
} catch (Exception e) {
System.err.println("Failed to send notification, but order was processed: " + e.getMessage());
}
}
}
}import io.micronaut.context.ApplicationContext;
import java.util.Optional;
@Singleton
public class FlexibleService {
private final Optional<CacheService> cacheService;
private final Optional<MetricsService> metricsService;
@Inject
public FlexibleService(ApplicationContext context) {
this.cacheService = context.findBean(CacheService.class);
this.metricsService = context.findBean(MetricsService.class);
}
public String getData(String key) {
// Try cache first if available
if (cacheService.isPresent()) {
String cached = cacheService.get().get(key);
if (cached != null) {
metricsService.ifPresent(metrics -> metrics.increment("cache.hit"));
return cached;
}
}
// Fetch from database
String data = fetchFromDatabase(key);
// Cache if service available
cacheService.ifPresent(cache -> cache.put(key, data));
metricsService.ifPresent(metrics -> metrics.increment("cache.miss"));
return data;
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.BeanInstantiationException;
@Singleton
public class RetryableService {
private ExternalService externalService;
private final int maxRetries = 3;
@PostConstruct
public void initialize() {
// Retry bean creation with backoff
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
this.externalService = createExternalService();
break;
} catch (BeanInstantiationException e) {
System.err.println("Attempt " + attempt + " failed: " + e.getMessage());
if (attempt == maxRetries) {
System.err.println("All attempts failed, using fallback service");
this.externalService = new FallbackExternalService();
} else {
// Wait before retry
try {
Thread.sleep(1000 * attempt);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.inject.BeanDefinition;
public class BeanDebuggingUtils {
public static void debugBeanResolution(ApplicationContext context, Class<?> beanType) {
System.out.println("Debugging bean resolution for: " + beanType.getSimpleName());
// Check if bean exists
boolean exists = context.containsBean(beanType);
System.out.println("Bean exists: " + exists);
if (!exists) {
// Show similar beans
System.out.println("Similar beans:");
context.getBeanDefinitions(Object.class).stream()
.filter(def -> def.getBeanType().getSimpleName().contains(beanType.getSimpleName()))
.forEach(def -> System.out.println(" - " + def.getBeanType().getName()));
} else {
// Show bean details
Collection<BeanDefinition<?>> definitions = context.getBeanDefinitions(beanType);
System.out.println("Found " + definitions.size() + " bean(s):");
for (BeanDefinition<?> def : definitions) {
System.out.println(" Bean: " + def.getBeanType().getName());
System.out.println(" Scope: " + (def.isSingleton() ? "Singleton" : "Prototype"));
System.out.println(" Constructor args: " + def.getConstructorArguments().size());
System.out.println(" Injected methods: " + def.getInjectedMethods().size());
System.out.println(" Injected fields: " + def.getInjectedFields().size());
}
}
}
public static void listAllBeans(ApplicationContext context) {
System.out.println("All registered beans:");
context.getBeanDefinitions(Object.class).stream()
.sorted((a, b) -> a.getBeanType().getName().compareTo(b.getBeanType().getName()))
.forEach(def -> {
System.out.println(" " + def.getBeanType().getName() +
" [" + (def.isSingleton() ? "Singleton" : "Prototype") + "]");
});
}
}import io.micronaut.context.exceptions.BeanContextException;
public class ExceptionAnalyzer {
public static void analyzeBeanException(BeanContextException e) {
System.err.println("=== Bean Exception Analysis ===");
System.err.println("Exception type: " + e.getClass().getSimpleName());
System.err.println("Message: " + e.getMessage());
// Analyze specific exception types
if (e instanceof NoSuchBeanException) {
NoSuchBeanException nsbe = (NoSuchBeanException) e;
System.err.println("Missing bean type: " + nsbe.getBeanType());
if (nsbe.getQualifier() != null) {
System.err.println("Required qualifier: " + nsbe.getQualifier());
}
} else if (e instanceof NonUniqueBeanException) {
NonUniqueBeanException nube = (NonUniqueBeanException) e;
System.err.println("Ambiguous bean type: " + nube.getBeanType());
System.err.println("Candidates (" + nube.getPossibleCandidates().size() + "):");
nube.getPossibleCandidates().forEach(candidate ->
System.err.println(" - " + candidate.getBeanType().getName()));
} else if (e instanceof BeanInstantiationException) {
BeanInstantiationException bie = (BeanInstantiationException) e;
if (bie.getBeanDefinition() != null) {
System.err.println("Failed bean: " + bie.getBeanDefinition().getBeanType());
}
}
// Show cause chain
Throwable cause = e.getCause();
int level = 1;
while (cause != null) {
System.err.println("Cause " + level + ": " + cause.getClass().getSimpleName() +
" - " + cause.getMessage());
cause = cause.getCause();
level++;
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-micronaut--micronaut-inject