1

I work with a legacy springboot application which has a huge com.mycompany.MyApplication class where there are injected a bunch of spring objects through @Autowire annotation. Trying to split MyApplication class up, I created several classes and put them in different packages but I got an issue with CouchbaseCluster autowire injection; the error is:

AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myApplication': Unsatisfied dependency expressed through field 'step'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobSteps': Unsatisfied dependency expressed through field 'couchbaseFlushCacheTasklet'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'couchbaseFlushCacheTasklet': Unsatisfied dependency expressed through field 'cluster'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.couchbase.client.java.CouchbaseCluster' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}


***************************
APPLICATION FAILED TO START
***************************

Description:

Field cluster in com.mycompany.batch.tasklet.CouchbaseFlushCacheTasklet required a bean of type 'com.couchbase.client.java.CouchbaseCluster' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:
Consider defining a bean of type 'com.couchbase.client.java.CouchbaseCluster' in your configuration.

Here is an example of my code:

package com.mycompany;

@EnableBatchProcessing
@SpringBootApplication
public class MyApplication implements CommandLineRunner {

    @Autowired
    JobSteps step;

    ...
}
package com.mycompany.batch;

@Configuration
public class JobSteps {

    @Autowired
    CouchbaseFlushCacheTasklet couchbaseFlushCacheTasklet;

    @Autowired
    CouchbaseDeleteNonBatchTasklet couchbaseDeleteNonBatchTasklet;

    ...

}

If you note in the next code snipped, cluster uses the @SuppressWarnings annotation because Intellij marks this with this error: 'Could not autowire. No beans of 'CouchbaseCluster' type found.' however it was before and after my changes, but before the application ran without issues.

package com.mycompany.batch.tasklet;

@Component
public class CouchbaseFlushCacheTasklet {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    CouchbaseCluster cluster;

    ...
}

I am putting this next class to show that there is any problem with the bean Budget, which is located in the same library/package than CouchbaseCluster com.couchbase.client.java.Bucket

package com.mycompany.batch.tasklet;

@Component
public class CouchbaseDeleteNonBatchTasklet {

    @Autowired
    Bucket bucket;

    ...
}

POM dependencies associated with couchbase

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-couchbase</artifactId>
            <version>3.1.9.RELEASE</version>
        </dependency>

I tried to specify the scanBasePackeges but didn't work.

@SpringBootApplication(scanBasePackages = {"com.mycompany", "com.couchbase.client"})

Any clue will be appreciated since I have spent a lot of time looking for a solution and so far none of the suggested things in similar posts have worked.

I solved it :-) Instead of autowire this

    @Autowired
    CouchbaseCluster cluster;

I autowire this

    @Autowired
    Cluster cluster;

I am not sure how was possible that at some point it worked autowiring CouchbaseCluster

JeromeTech
  • 13
  • 4

2 Answers2

0

First thing CouchbaseCluster class should be part of the bean life cycle, it should be annotated with an annotation like @Component etc. if so you must check you should not be creating the object of any class using the new keyword. So in your case, it will be resolved something like this. add the below method into JobSteps.

@Bean 
public CouchbaseCluster couchbaseCluster(){

 CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
            .bootstrapCarrierDirectPort(couchbase.getMappedPort(11210))
            .bootstrapCarrierSslPort(couchbase.getMappedPort(11207))
            .bootstrapHttpDirectPort(couchbase.getMappedPort(8091))
            .bootstrapHttpSslPort(couchbase.getMappedPort(18091))
            .build();
    CouchbaseCluster cc = CouchbaseCluster.create(env);

    return cc;

    }

Modified the CouchbaseEnvironment object according to your configuration.

rahul sharma
  • 505
  • 4
  • 17
-1

Have you tried creating your Cluster in the @PostConstruct?

@Service
public class CouchbaseFlushCacheTasklet {
    private Cluster cluster;

    @PostConstruct
    private void init() {
        CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create();
        cluster = CouchbaseCluster.create(env, "localhost");
    }
...
}

Code from: https://www.baeldung.com/couchbase-sdk-spring

Alternatively, try adding an @Bean producer somewhere instead of using a @PostConstruct.

Tom Cools
  • 1,098
  • 8
  • 23