Spring Batch configuration NoSuchMethodError Exception - java

This is the first time I am using Spring batch and I have an exception :
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stepScope' defined in class path resource [org/springframework/batch/core/configuration/annotation/StepScopeConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.batch.core.scope.StepScope org.springframework.batch.core.configuration.annotation.StepScopeConfiguration.stepScope()] threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.batch.core.scope.StepScope.setAutoProxy(Z)V
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1031)
....
Caused by: java.lang.NoSuchMethodError: org.springframework.batch.core.scope.StepScope.setAutoProxy(Z)V
at org.springframework.batch.core.configuration.annotation.StepScopeConfiguration.stepScope(AbstractBatchConfiguration.java:130)
I don't know how to solve this error. I am using a Java configuration to define the job, the step, the reader, the processor and the writer :
public class SpringBatchTestJobConfig extends PersistenceSpringConfig {
#Autowired
private JobBuilderFactory jobBuilders;
#Autowired
private StepBuilderFactory stepBuilders;
#Bean
#StepScope
public FlatFileItemReader<EntiteJuridique> cvsReader(#Value("#{jobParameters[input.file]}") String input)
{
log.info("cvsReader");
FlatFileItemReader<EntiteJuridique> flatFileReader = new FlatFileItemReader<EntiteJuridique>();
flatFileReader.setLineMapper(lineMapper());
flatFileReader.setResource(new ClassPathResource(input));
return flatFileReader;
}
#Bean
public ItemWriter<EntiteJuridiqueJPA> writer()
{
log.info("writer");
JpaItemWriter<EntiteJuridiqueJPA> jpaWriter = new JpaItemWriter<EntiteJuridiqueJPA>();
try
{
jpaWriter.setEntityManagerFactory(entityManagerFactory().nativeEntityManagerFactory);
}
catch (Exception exception)
{
log.debug(exception);
}
return jpaWriter;
}
#Bean
public Job dataInitializer()
{
return jobBuilders.get("dataInitializer").start(step()).build();
}
#Bean
public Step step()
{
return stepBuilders.get("step").<EntiteJuridique, EntiteJuridiqueJPA> chunk(1).reader(cvsReader(null)).processor(processor())
.writer(writer()).build();
}
Any clues to how this problem?
EDIT : I am using
spring-core 3.2.2.RELEASE
spring-batch 2.2.0.RELEASE
spring-batch-infrastructure 2.2.0.RELEASE
spring-test 3.2.2.RELEASE

I got this same error, the solution for me was removing the version from my dependency and it worked fine.
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</dependency>

Related

Autowiring fails in Junit testing and spring #configuration

I have two #Configuration classes. I need a bean from one configuration class to another. I have autowired the configuration 1 into 2. All works fine. When executing the unit testing, am getting the below exception.
setUpContext(com.trafigura.titan.framework.services.messaging.loader.SpringLoadTest)
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.xxx.MessagingServicesConfig': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.EMSJMSConfig com.xxx.MessagingServicesConfig.emsJmsConfig;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type[com.xxx.EMSJMSConfig] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Is there anything I need to do additionally to make this working?
Below is the setup for testing.
#Configuration
#Import({MessagingServicesConfig.class,...,EMSJMSConfig.class
})
public class MessagingConfig {}
#Profile("EMS-MESSAGING")
#Configuration
public class EMSJMSConfig {
#Bean
public javax.jms.ConnectionFactory jmsSubscriberConnectionFactory() throws JMSException {
SingleConnectionFactory singleConnectionFactory = new SingleConnectionFactory(tibjmsConnectionFactory());
return singleConnectionFactory;
}
}
#Configuration
public class MessagingServicesConfig {
#Autowired
private EMSJMSConfig emsJmsConfig;
#Bean(destroyMethod = "shutdown")
public MessagingService messagingService() throws JMSException {
...
ConnectionFactory cf=emsJmsConfig.jmsSubscriberConnectionFactory(); // Getting NPE at this line.
}
}
and finally the test class,
public class MessagingServicesConfigTest {
private MessagingServicesConfig config;
private EMSJMSConfig emsJmsConfig;
#BeforeMethod
public void setUp() throws Exception {
config = new MessagingServicesConfig();
... //what needs to be done here to have the EMSJMSConfig
}
#Test
public void testBuildsCorrectService() throws JMSException {
MessagingService service = config.messagingService();
...
}
}
By calling new you're creating object yourself, Spring doesn't know anything about it.
Moreover, you should have a test configuration which will be aware of your beans.
Use an appropriate Runner to load SpringContext.
#ContextConfiguration(classes = TestConfig.class)
#RunWith(SpringRunner.class)
class Tests {
#Autowired // if needed
private MessagingServicesConfig config;
}
While in TestConfig you can create beans or import configuration from the Application:
#Configuration
#Import({MessagingServicesConfig.class})
public class TestConfig {}
#Configuration
#Import({EMSJMSConfig.class})
public class MessagingServicesConfig {}
Or you can refer to your config classes directly:
#ContextConfiguration(classes = {MessagingServicesConfig.class, EMSJMSConfig.class})

Spring boot : delegateBuilder cannot be null on autowiring authenticationManager in custom UserDetailsService

Hi i'm new to spring boot and trying implement the security to my rest apis.
i'm using spring boot 2.0.7.release
i have configures my WebSecurityConfig as following
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Resource(name = "userService")
private UserDetailsService userDetailsService;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
#Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
#Bean
public PasswordEncoder encoder(){
PasswordEncoder encoder = new CustomPasswordEncoder();
return encoder;
}
....
}
I have add the resource name so that i can point the to custom userDetailsService.
I have tried configuring authenticationManager Bean by came and pointing the bean by Qualifier authenticationManager bean still it the error remains same.
my pom.xml looks like for security
......
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
......
and my implemented UserServiceImpl is
#Service(value = "userService")
public class UserServiceImpl implements UserService, UserDetailsService {
#Autowired
private UserDAOService userDao;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("Invalid username or password.");
}
return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), getAuthority());
}
#Override
public String login(LoginUser user) {
// valid user if it exits then do the following
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
//generate the token and do other process.
}
following are the error logs. i have provided only mail errors
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager' defined in class path resource [com/saikrishna/security/config/WebSecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Circular reference involving containing bean 'webSecurityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'authenticationManagerBean' threw exception; nested exception is java.lang.IllegalArgumentException: delegateBuilder cannot be null
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager' defined in class path resource [com/saikrishna/security/config/WebSecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Circular reference involving containing bean 'webSecurityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'authenticationManagerBean' threw exception; nested exception is java.lang.IllegalArgumentException: delegateBuilder cannot be null
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager' defined in class path resource [com/saikrishna/security/config/WebSecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Circular reference involving containing bean 'webSecurityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'authenticationManagerBean' threw exception; nested exception is java.lang.IllegalArgumentException: delegateBuilder cannot be null
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Circular reference involving containing bean 'webSecurityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'authenticationManagerBean' threw exception; nested exception is java.lang.IllegalArgumentException: delegateBuilder cannot be null
Caused by: java.lang.IllegalArgumentException: delegateBuilder cannot be null
at org.springframework.util.Assert.notNull(Assert.java:193) ~[spring-core-5.0.11.RELEASE.jar:5.0.11.RELEASE]
In order to help you better, it is better if you indicate which reference you are following to implement JWT mechansim.
Conceptually, this part of the source code is wrong:
#Override
public String login(LoginUser user) {
// valid user if it exits then do the following
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
//generate the token and do other process.
}
See if the modifications below can help you
1) Consider using Java Config to declare your beans, in a seperate Configuration class
#Configuration
public class ServiceConfig{
#Bean
protected UserDAOService daoService()
{
return new UserDAOServiceImpl();
}
#Bean
protected UserDetailsService userDetailService( UserDAOService dao )
{
return new UserServiceImpl( dao );
}
#Bean
public PasswordEncoder encoder(){
PasswordEncoder encoder = new CustomPasswordEncoder();
return encoder;
}
#Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception{ {
return new JwtAuthenticationFilter();
}
}
2) Modification to your WebSecurityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Override
protected void configure( AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService( userDetailsService ).passwordEncoder( passwordEncoder );
}
}

Error creating mongobee bean on springboot app (on run of tests)

I use all lasts versions (fix others problems)
mongobee 0.13
fongo 2.2.0-RC3-SNAPSHOT
mongodb-driver 3.8.2
When I run my app, I have this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongobeeStandalone' defined in class path resource [com/myproject/company/configuration/MongoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError: com.mongodb.client.internal.FongoOperationExecutor.execute(Lcom/mongodb/operation/ReadOperation;Lcom/mongodb/ReadPreference;Lcom/mongodb/ReadConcern;)Ljava/lang/Object; ... Caused by: java.lang.AbstractMethodError: com.mongodb.client.internal.FongoOperationExecutor.execute(Lcom/mongodb/operation/ReadOperation;Lcom/mongodb/ReadPreference;Lcom/mongodb/ReadConcern;)Ljava/lang/Object;
My class:
#Bean
public Mongobee mongobeeStandalone(final MongoTemplate mongoTemplate, final MongoClient mongoClient) {
final Mongobee runner = new Mongobee(mongoClient);
runner.setChangeLogsScanPackage(Changelog1.class.getPackage().getName()); // package to scan for changesets
runner.setDbName(mongoTemplate.getDb().getName());
return runner;
}
#Bean
public MongoClient mongoClient(final MongoDbFactory mongoDbFactory) {
final Mongo mongo = mongoDbFactory.getLegacyDb().getMongo();
if (!MongoClient.class.isInstance(mongo)) {
throw new UnsupportedOperationException("Must be a MongoClient");
}
return MongoClient.class.cast(mongo);
}
EDIT
My test configuration:
#Configuration
public class FoncgoConfiguration extends AbstractMongoConfiguration {
#Bean
public Fongo fongo() {
return new Fongo("mongo-test");
}
#Override
#Bean
public MongoTemplate mongoTemplate() throws Exception {
final SimpleMongoDbFactory simpleMongoDbFactory = new SimpleMongoDbFactory(mongoClient(), getDatabaseName());
final MongoTemplate mongoTemplate = new MongoTemplate(simpleMongoDbFactory, mappingMongoConverter());
return mongoTemplate;
}
#Override
#Bean
public MongoClient mongoClient() {
return MockMongoClient.create(fongo());
}
}
You should use Spring Data Mongo, it will create and inject com.mongodb.MongoClient bean. So remove mongoClient() method and add the Mongodb Spring Data dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Spring Boot also provides a MongoTemplate bean and auto-configures it. For testing you should use Embedded Mongo with #DataMongoTest annotation, because it configures a MongoTemplate. See here for test examples.

How to I configure my own GraphDatabaseService and GraphAwareRuntime in a spring unit test with boot 2.0 and Neo4j SDN5

I'm writing some unit tests and want to use TimeTree along with Spring repositories, to auto attach event nodes to a time tree. Something like this issue, but I'm using boot 2.0 and SDN5. I think my main issue is I don't know how to set up the configuration so my repositories and my TimeTree use the same GraphDatabaseService. My #Confuration is like this:
#Configuration
public class SpringConfig {
#Bean
public SessionFactory sessionFactory() {
// with domain entity base package(s)
return new SessionFactory(configuration(), "org.neo4j.boot.test.domain");
}
#Bean
public org.neo4j.ogm.config.Configuration configuration() {
return new org.neo4j.ogm.config.Configuration.Builder()
.uri("bolt://localhost")
.build();
}
#Bean
public Session getSession() {
return sessionFactory().openSession();
}
#Bean
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory()
.newEmbeddedDatabase(new File("/tmp/graphDb"));
}
#Bean
public GraphAwareRuntime graphAwareRuntime() {
GraphDatabaseService graphDatabaseService = graphDatabaseService();
GraphAwareRuntime runtime = GraphAwareRuntimeFactory
.createRuntime(graphDatabaseService);
runtime.registerModule(new TimeTreeModule("timetree",
TimeTreeConfiguration
.defaultConfiguration()
.withAutoAttach(true)
.with(new NodeInclusionPolicy() {
#Override
public Iterable<Node> getAll(GraphDatabaseService graphDatabaseService) {
return null;
}
#Override
public boolean include(Node node) {
return node.hasLabel(Label.label("User"));
}
})
.withRelationshipType(RelationshipType.withName("CREATED_ON"))
.withTimeZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("GMT+1")))
.withTimestampProperty("createdOn")
.withResolution(Resolution.DAY)
// .withCustomTimeTreeRootProperty("timeTreeName")
.withResolution(Resolution.HOUR), graphDatabaseService));
runtime.start();
return runtime;
}
}
And my test looks like this:
User user = new User("Michal");
user.setCreatedOn(1431937636995l);
userRepository.save(user);
GraphUnit.assertSameGraph(graphDb, "CREATE (u:User {name:'Michal', createdOn:1431937636995})," +
"(root:TimeTreeRoot)," +
"(root)-[:FIRST]->(year:Year {value:2015})," +
"(root)-[:CHILD]->(year)," +
"(root)-[:LAST]->(year)," +
"(year)-[:FIRST]->(month:Month {value:5})," +
"(year)-[:CHILD]->(month)," +
"(year)-[:LAST]->(month)," +
"(month)-[:FIRST]->(day:Day {value:18})," +
"(month)-[:CHILD]->(day)," +
"(month)-[:LAST]->(day)," +
"(day)<-[:CREATED_ON]-(u)"
);
GraphUnit.printGraph(graphDb);
graphDb.shutdown();
There's a host of errors, but I think they all stem from this one:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.springframework.data.repository.support.Repositories]:
Factory method 'repositories' threw exception; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error
creating bean with name 'userRepository': Unsatisfied dependency
expressed through method 'setSession' parameter 0; nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.neo4j.ogm.session.Session' available:
expected single matching bean but found 2: getSession,
org.springframework.data.neo4j.transaction.SharedSessionCreator#0
It is because the configuration class redefines some beans already automatically configured by Spring boot (here the Session).
So spring injection does not know how to choose between the 2.
Removing the getSession() should help.
A second thing is that your SessionFactory has to use the embedded DB setup in the graphDatabaseService() method. For this, configure an embedded driver with the existing database.
Summary config that should work fine for you :
#Bean
public SessionFactory sessionFactory() {
EmbeddedDriver driver = new EmbeddedDriver(graphDatabaseService());
return new SessionFactory(driver, "org.neo4j.boot.test.domain");
}
#Bean
public PlatformTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
#Bean
public GraphDatabaseService graphDatabaseService() {
return new TestGraphDatabaseFactory().newImpermanentDatabaseBuilder().newGraphDatabase();
}
#Bean
public GraphAwareRuntime graphAwareRuntime() {
...

Spring Autowiring Beans giving Class Cast Exception

Here is my class
#Configuration
class MongoDBConfig {
private Logger logger = LoggingFactory.getLogger(getClass());
#Bean
#Scope(value = "singleton", proxyMode = ScopedProxyMode.INTERFACES)
public MongoClient mongoClient() throws UnknownHostException {
logger.error("In Dev mode:");
return new MongoClient("fctest");
}
#Bean
public DB mongoDB() throws UnknownHostException{
try {
return mongoClient().getDB(FCProperties.MONGO_DB_NAME);
}catch (UnknownHostException ue){
logger.error("Error occurred: "+ue.getMessage());
throw ue;
}
}
}
And here is how I'm using it -
public class UserRepository extends BaseRepository {
#Autowired
public UserRepository(DB mongoDB) {
super("users", mongoDB);
}
}
I'm getting the following error
Error creating bean with name 'mongoDB' defined in class path resource [com/fctest/mongo/config/MongoDBConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public com.mongodb.DB com.fctest.mongo.config.MongoDBConfig.mongoDB() throws java.net.UnknownHostException] threw exception; nested exception is java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to com.mongodb.MongoClient

Categories