I am trying to build my own DiscoveryClient that would use Docker Swarm as the service source. I got it working with Spring Cloud Gateway and Spring Cloud Loadbalancer already. However, when I tried to use it to do discovery for the configserver by setting spring.cloud.config.discovery.enabled=true I get the following error
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.client.discovery.DiscoveryClient' available: expected at l
east 1 bean which qualifies as autowire candidate. Dependency annotations: {}
I have created AutoConfigure classes as well but no luck. The project is here https://github.com/trajano/spring-cloud-demo.
When looking at the debug logs, with and without the discovery, it appears that the AutoConfiguration beans do not load up in the CONDITIONS EVALUATION REPORT specifically the ones in other libraries.
Similar to Spring cloud discovery first does not work at all but they are using Eureka, whereas I am trying to determine how to build my own DiscoveryClient.
I see your Configuration class for the DiscoveryClient has these annotations:
#ConditionalOnDiscoveryEnabled
#ConditionalOnBlockingDiscoveryEnabled
#ConditionalOnDockerSwarmDiscoveryEnabled
#AutoConfigureAfter({
DockerSwarmDiscoveryAutoConfiguration.class
})
#AutoConfigureBefore({
SimpleDiscoveryClientAutoConfiguration.class,
CommonsClientAutoConfiguration.class
})
Could it be those settings are not enabled?
You mention you enabled discovery, but you do not mention the other ConditionOnX configurations.
If they are not enabled, the bean would not load.
There was a separate set of org.springframework.boot.autoconfigure.EnableAutoConfiguratio elements in spring.factory called org.springframework.cloud.bootstrap.BootstrapConfiguration
So I added this
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
net.trajano.spring.swarm.discovery.DockerSwarmDiscoveryClientConfigServiceBootstrapConfiguration
And this class
#ConditionalOnClass(ConfigServicePropertySourceLocator.class)
#ConditionalOnProperty("spring.cloud.config.discovery.enabled")
#Configuration(proxyBeanMethods = false)
#Import({
DockerSwarmDiscoveryClientAutoConfiguration.class,
// this emulates
// #EnableDiscoveryClient, the import
// selector doesn't run before the
// bootstrap phase
DockerClientConfiguration.class,
DockerSwarmDiscoveryAutoConfiguration.class,
DockerSwarmReactiveDiscoveryClientAutoConfiguration.class,
ReactiveCommonsClientAutoConfiguration.class
})
public class DockerSwarmDiscoveryClientConfigServiceBootstrapConfiguration {
}
Related
I have application with spring-boot-starter-actuator dependency. When I add my error handling library as dependency, application fails to start with the following message
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
After a bit research, I found out the error handling library introduces transitive dependency of spring-boot-starter-data-jpa which in turn causes actuator autoconfiguration to automatically introduce DataSourceHealthIndicator bean. This bean fails on missing database connection, but the application actually doesn't use database at all. However, the logging library requires the JPA dependency at runtime, so I can't exclude it.
I tried to set the following application property: management.health.db.enabled=false, but I still get the same error on startup. I can't find any documentation how to disable DataSourceHealthIndicator bean and leaving other autoconfiguration intact.
My project does use Redis but my unit test mocks it. However it doesn't mock it enough because I get this stack trace snippet:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'redisReferenceResolver': Cannot resolve reference to bean 'redisTemplate' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'redisTemplate' available
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)
It is correct. I have carefully ensured there is no redisTemplate bean available because I don't want to run redis in my unit test. But I don't know why it is trying to create the redisReferenceResolver bean.
I've turned off autoconfiguration with this:
spring:
profiles: RedisMock
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
(my test has #ActiveProfiles({"WebMvcTest","RedisMock"}) in the top)
I do have one class annotated with #RedisHash but I need that for my test.
Anyone know what might be triggering the autoconfigure?
Thanks
redisReferenceResolver is defined by Spring Data’s support for Redis-based repositories. Setting spring.data.redis.repositories.enabled to false and ensuring that you haven’t used #EnableRedisRepositories anywhere in your app will disable it.
I have Spring Boot app that creates a RESTful API. It wants to automatically connect to port 27017, I believe because it contains a transitive dependency to MongoDB.
But I don't want it to auto-connect to MongoDB because that server may not yet have started, thus throwing an error.
So I exclude the Mongo AutoConfiguration classes from the app like so:
#SpringBootApplication(exclude = {
MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class
})
But then I get this error:
Parameter 0 of constructor in com.whatev.MyLogImpl required a bean named 'mongoTemplate' that could not be found.
Why does it need an mongoTemplate when I'm excluding Mongo AutoConfiguration?
But nonetheless, I then added a new #Configuration class containing MongoTemplate, but I get:
Parameter 0 of constructor in com.whatevz.MongoFileService required a bean of type 'org.springframework.data.mongodb.gridfs.GridFsTemplate' that could not be found.
- Bean method 'gridFsTemplate' not loaded because auto-configuration 'MongoDataAutoConfiguration' was excluded
True, I excluded the MongoDataAutoConfiguration class. But I don't want to also exclude gridFsTemplate if that's gonna cause a problem. Sheesh.
All I want to do is not see an error when I start my app if MongoDB is not yet running.
When using org.springframework.cloud:spring-cloud-gcp-starter-trace:1.0.0.RELEASE and running my integration tests locally I get this error message:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'stackdriverSender' defined in class path
resource
[org/springframework/cloud/gcp/autoconfigure/trace/StackdriverTraceAutoConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [zipkin2.reporter.Sender]: Factory method
'stackdriverSender' threw exception; nested exception is
java.io.IOException: The Application Default Credentials are not
available. They are available if running in Google Compute Engine.
Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS
must be defined pointing to a file defining the credentials. See
https://developers.google.com/accounts/docs/application-default-credentials
for more information.
This is totally understandable since this environment variable is not present locally and I don't want to use Sleuth/Stackdriver tracing when running the tests. I've looked in the reference documentation but I can only seem to find information on how to disable Sleuth for specific integration points such as RxJava, RestTemplate etc. But how can I disable Sleuth entirely?
I've tried setting spring.sleuth.enabled=false but this doesn't seem to make any difference.
HowTo: Disable all tests for a Webflux Sleuth implementation with Zipkin
If, you have these dependencies:
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
implementation 'org.springframework.cloud:spring-cloud-sleuth-zipkin'
Then, fully disable Sleuth/Zipkin for your integration tests by adding an application.yml to your test/resources folder with:
spring:
sleuth: # All sleuth features disabled for integration tests
enabled: false
reactor:
enabled: false
web:
enabled: false
async:
enabled: false
client:
template:
enabled: false
zipkin: # All zipkin features disabled for integration tests
enabled: false
I actually found the answer by looking at the source for the StackdriverTraceAutoConfiguration class. The way to solve it if using GCP is to set spring.cloud.gcp.trace.enabled=false. This disables tracing for all integration points.
You can disable tracing, logging and set a fake project id as follow:
spring.cloud.gcp.project-id=fake-project-id
spring.cloud.gcp.logging.enabled=false
spring.cloud.gcp.trace.enabled=false
I am attempting to convert an existing spring weblogic application to a spring boot embedded tomcat application.
There are lots of moving parts so it's hard to show any code, I'm hoping there is some general answer that might clue me in to the issue.
Under weblogic, using the spring-framework 4.3.6.RELEASE libraries, the application deploys fine. It has no problems creating the different service, repository and component beans.
However, when I migrate it to Spring Boot 1.5.1.RELEASE, I get the following error:
2017-06-21 17:08:16,402 [ERROR] SpringApplication reportFailure (815) - Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'alertEventServiceImpl': Unsatisfied dependency expressed through field 'alertEventDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'alertEventDaoImpl' defined in URL [jar:file:/Users/username/Development/source/carma-war/target/carma-war-2.0.0-SNAPSHOT.war!/WEB-INF/lib/protocol-manager-1.8.0-SNAPSHOT.jar!/org/ihc/hwcir/protocol/dao/AlertEventDaoImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl
Many of our service classes are final as they shouldn't be extended. Since there are so many that are final, I wanted to minimize the amount of code in our different libraries that we modify to make this work.
I thought because the bean creation process works under weblogic, it should work under spring boot.
Things I have tried to force not using the cglib proxies:
All implementations implement interfaces already
In beans created via xml, added <aop:scoped-proxy proxy-target-class="false"/>
In beans created through annotations, added (example for service bean)
#Service
#Scope(proxyMode = ScopedProxyMode.INTERFACE)
However, in the end, I'm perplexed as to why spring can create beans (the classes marked as final) under the weblogic container but unable to do so under the embedded tomcat spring-boot container.
Spring Boot by default uses class based proxies, which will not work with final classes/methods.
To disable this add spring.aop.proxy-target-class=false to the application.properties to enable JDK Dynamic Proxies instead of class based proxies. (And revert your modifications).
NOTE: To have everything take into account the spring.aop.proxy-target-class you might need to upgrade to Spring Boot 1.5.3 as some final patches where made to include this property in parts that were missed in previous versions.
See the following issues for more information 8434, 8869 and 8887.
I was unable to make this work using M. Deinums' answer using spring.aop.proxy-target-class=false.
What worked for me was to add in the application.properties file
spring.dao.exceptiontranslation.enabled=false
Please note that this option disables proxy creation for repositories.
And in my spring boot application configurer the annotation to handle transactions without using a proxy class.
#EnableTransactionManagement(proxyTargetClass = false)
This is using Spring Boot version 1.5.1.RELEASE.