Understanding the Problem
The UnsatisfiedDependencyException
in your Spring Boot application arises due to a misconfigured PoolingHttpClientConnectionManager
bean. The error explicitly states:
java.lang.IllegalArgumentException: Max per route value may not be negative or zero
This occurs when the parameters httpConnMaxTotal
and httpConnMaxPerRoute
in your connectionManagerTest()
method are not properly initialized, leading to invalid values (≤ 0) for connection pool limits.
Root Cause Analysis
- Missing Property Injection
The@Value
annotations forhttpConnMaxTotal
andhttpConnMaxPerRoute
are likely missing or pointing to undefined properties in yourapplication.properties
/application.yml
file. For example:
@Value("${http.conn.max.total}") // Ensure these properties exist
private int httpConnMaxTotal;
@Value("${http.conn.max.per.route}")
private int httpConnMaxPerRoute;
If these properties are not set, Spring defaults to 0
, triggering the error.
- Profile-Specific Configuration
The@Profile({"test", "default"})
annotation indicates this bean is active only in specific environments. If your test environment lacks these properties, the values default to0
. - ShedLock Configuration Conflicts
Adding ShedLock may interfere with existing beans (e.g.,ScheduledExecutorService
), especially ifPROXY_SCHEDULER
mode is used. However, in this case, the primary issue is unrelated to ShedLock itself but stems from the connection manager setup.
Step-by-Step Fix
1. Validate Property Values
Ensure your properties file (e.g., application-test.properties
) includes:
http.conn.max.total=20 # Example value > 0
http.conn.max.per.route=10
Always use positive integers for connection pool limits.
2. Fix the Bean Configuration
Update the connectionManagerTest()
method to avoid duplicate setDefaultMaxPerRoute
calls and ensure correct property injection:
@Profile({"test", "default"})
@Bean(name = "connectionManager")
public PoolingHttpClientConnectionManager connectionManagerTest(
@Value("${http.conn.max.total}") int maxTotal,
@Value("${http.conn.max.per.route}") int maxPerRoute) {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(maxTotal); // Set max total connections
connManager.setDefaultMaxPerRoute(maxPerRoute); // Set per-route limit
return connManager;
}
3. Verify ShedLock Configuration
While ShedLock isn’t the direct cause here, ensure its setup doesn’t conflict with other beans:
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT10M")
public class ShedLockConfig {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
}
Avoid defining multiple ScheduledExecutorService
beans unless necessary.
Preventing Future Issues
- Use Constructor Injection: Reduces ambiguity in dependency resolution.
- Profile-Specific Properties: Define environment-specific configurations to avoid defaulting to invalid values.
- Integration Tests: Validate bean creation in test environments using
@SpringBootTest
.
Conclusion
The error stems from uninitialized properties for HTTP connection limits, not ShedLock itself. By ensuring proper property injection and validating profile-specific configurations, you can resolve the UnsatisfiedDependencyException
and maintain robust distributed task scheduling with ShedLock. For further ShedLock best practices, refer to 42talents.com.
Need more help? Explore Baeldung’s guide on dependency resolution in Spring.