Duplication Job in Spring Batch - java

Getting error Cannot Register Job Configuration because DuplicationJobException After Upgrade to Spring 2.x
Already checked, there is no duplicate name in my code.
The Error
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:558)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobCalcSampleDetail' defined in class path resource [id/co/a/microservice/batch/job/SampleJobConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.FatalBeanException: Cannot register job configuration; nested exception is org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [jobCalcSampleDetail] was already registered
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at id.co.a.microservice.batch.NcsBatchServiceApplication.main(NcsBatchServiceApplication.java:15)
... 6 more
Caused by: org.springframework.beans.FatalBeanException: Cannot register job configuration; nested exception is org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [jobCalcSampleDetail] was already registered
at org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor.postProcessAfterInitialization(JobRegistryBeanPostProcessor.java:150)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:429)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
... 21 more
Caused by: org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [jobCalcSampleDetail] was already registered
at org.springframework.batch.core.configuration.support.MapJobRegistry.register(MapJobRegistry.java:52)
at org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor.postProcessAfterInitialization(JobRegistryBeanPostProcessor.java:146)
... 24 more
Job Configuration Code
#Configuration
#EnableBatchProcessing
public class SampleJobConfiguration {
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
#Autowired
public PostgresDbConfig postgres;
#Value("${xxx.chunk.default}")
private int chunkSize;
#Value("${xxx.limit.retry}")
private int retryLimit;
#Bean
#StepScope
public Tasklet taskletRmvSample(#Value("#{jobParameters['period']}") String period,
#Value("#{jobParameters['clearData']}") Boolean clearData) {
return (StepContribution stepContribution, ChunkContext chunkContext) -> {
if (clearData) {
new JdbcTemplate(postgres.dataSource()).execute("");
}
return RepeatStatus.FINISHED;
};
}
#Bean
public Step step1RmvSample() {
return stepBuilderFactory.get("step1RmvSampleDetail").tasklet(
taskletRmvSample(null, null)).build();
}
#Bean
public Job jobCalcSampleDetail() throws Exception {
return jobBuilderFactory.get("jobCalcSampleDetail").incrementer(new RunIdIncrementer()).start(
step1RmvSample()).build();
}
}
Main Application Code
#SpringBootApplication
#EnableDiscoveryClient
#EnableScheduling
public class NcsBatchServiceApplication {
public static void main(String[] args) {
SpringApplication.run(NcsBatchServiceApplication.class, args);
}
}
Used Spring Boot Parent 2.1.4 - Spring Batch Core 4.1.1
previously it s working fine when using spring 1.5.17 but after upgrade to spring 2.* is error.
Also tried to add make modular but still error
#EnableBatchProcessing(modular = true)
Package Structure image
Maybe somebody can help.
Thanks

In my case I had several jobs defined in different packages but if I created more than one job at a time (by toggling the #Configuration) the application threw a duplicateJobConfiguration Exception. After working through pretty much every solution presented by Google and StackOverflow I stumbled across my solution which was to remove from the class that included the Job bean a boilerplate post-processor that had been copied in from a code sample somewhere:
#Bean
public JobRegistryBeanPostProcessor edwJobRegistryBeanPostProcessor(JobRegistry
jobRegistry) {
JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new
JobRegistryBeanPostProcessor();
jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
return jobRegistryBeanPostProcessor;
}
Somehow the multiple instances of JobRegistryBeanPostProcessor were triggering the error even though each was given a unique name.

Related

Creating Resource type constructor with #Value threw BeanCreationException; nested NullPointerException

I am writing a springboot project, where I am picking a .properties file from application.properties
application.properties
sample.prop.file=com.example.handler/signature.properties
and have created a Component to pass this file as InputStream and initialise the Bean
Handler.java
#Component
public class Handler extends DefaultHandler {
private Resource properties;
public Handler(#Value("${sample.prop.file}") Resource properties) throws IOException {
this.properties = properties;
this.props = new Properties();
this.props.load(this.properties.getInputStream());
}
}
In my service I create an instance of Handler.java and add it as BindingProvider
Service.java
#Service
public class Service {
#Autowired
private Handler handler;
public void doSomething() {
//some logic
someMethod(handler);
}
After following some similar queries I am trying constructor injection and using #Autowired in my Service to make sure my #Component is initialised before it is called.
But still upon running the project I am getting an error below.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Handler' defined in file [/Users/abc/APP/testService/target/classes/com/example/handler/Handler.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.handler.Handler]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1320)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
... 32 common frames omitted
Any inputs/comments are appriciated.
Thanks!
If the file in classpath. put classpath: as follows.
#Value("classpath:${sample.prop.file}")
You should know that Resource is annotation and you can't create an instance of it.
So you may change properties from Resource to String because #Value("${sample.prop.file}") returns String. Your class may become like so:
#Component
public class Handler extends DefaultHandler {
private Properties props;
public Handler(#Value("${sample.prop.file}") String properties) throws IOException
{
this.props = new Properties();
String p = Paths.get(properties).toAbsolutePath().toString();
InputStream in = new FileInputStream(p);
this.props.load(in);
}
}
But make sure that the new file is accessable, i.e. in some absolute path!

Can I ensure properties are autowired in a specific order using Spring, or use a non-default constructor?

I have a requirement to dynamically create a Spring managed class which relies on properties passed through before being able to set one of its instantiated properties.
Ideally I would like to pass the required properties in the constructor, but Spring doesn't seem to allow use of non-default constructors when instantiating beans.
SubBean.java:
#Configuration
public class SubBean extends SuperBean {
#Autowired
private LdapTemplate ldapTemplate;
public SubBean() {
super();
}
#Bean
public LdapTemplate setLdapTemplate() {
LdapContextSource contextSource= new LdapContextSource();
int separatorLocation = this.string.indexOf('/', 8);
contextSource.setUrl(this.string.substring(0, separatorLocation));
contextSource.setBase(this.string.substring(separatorLocation + 1));
contextSource.setAnonymousReadOnly(true);
return new LdapTemplate(contextSource);
}
public List<Computer> searchDirectory() {
SearchControls searchControls = new SearchControls();
searchControls.setCountLimit(25);
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
List<Computer> computers = (List<Computer>) ldapTemplate.search(
LdapQueryBuilder.query().filter("OU=Domain Controllers"), new ComputerAttributesMapper());
return computers;
}
private class ComputerAttributesMapper implements AttributesMapper<Computer> {
#Override
public Computer mapFromAttributes(Attributes attributes) throws NamingException {
Computer computer = new Computer();
computer.setName((String) attributes.get("name").get(0));
return computer;
}
}
#Override
public void doStuff() {
List<Computer> computers = searchDirectory();
System.out.println(computers);
}
}
SpringBootConfiguration.java:
There are multiple types of SubBean so they need to be referenced as the superclass.
#SpringBootApplication
public class SpringBootConfiguration {
#Autowired
private ConfigFile configFile;
#Autowired
private AutowireCapableBeanFactory beanFactory;
public static void main(String[] args) {
SpringApplication.run(SpringBootConfiguration.class, args);
}
#Bean
//Load configuration from a JSON file
public ConfigFile configFile() throws JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
File file = new File("configuration.json");
ConfigFile cf = mapper.readValue(file, ConfigFile.class);
cf.setFile(file);
return cf;
}
#Bean
public CommandLineRunner run(RestTemplate restTemplate, ApplicationContext ctx) throws Exception {
return args -> {
System.out.println(configFile);
List<Poller> configuredPollers = configFile.getConfiguration().getPollers();
for (Poller p : configuredPollers) {
//The class name is specified in the JSON configuration file.
Class<SuperBean> clazz = (Class<SuperBean>) Class.forName(p.getType());
//Use Spring to set up the object - this will try to autowire the ldapTemplate property and fail
SuperBean superBean = (SuperBean) beanFactory.createBean(clazz, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
//Because the beanFactory only uses the default constructor, I have to explicitly set its properties
superBean.setString(p.getString());
superBean.doStuff();
}
};
}
}
When this runs, I get the Exception:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'subBean': Unsatisfied dependency expressed through field 'ldapTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'setLdapTemplate' defined in class path resource [test/SubBean.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ldap.core.LdapTemplate]: Circular reference involving containing bean 'subBean' - consider declaring the factory method as static for independence from its containing instance. Factory method 'setLdapTemplate' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:882)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at test.SpringBootConfiguration.main(SpringBootConfiguration.java:28)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'setLdapTemplate' defined in class path resource [test/SubBean.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ldap.core.LdapTemplate]: Circular reference involving containing bean 'subBean' - consider declaring the factory method as static for independence from its containing instance. Factory method 'setLdapTemplate' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:484)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1290)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1210)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
... 19 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ldap.core.LdapTemplate]: Circular reference involving containing bean 'subBean' - consider declaring the factory method as static for independence from its containing instance. Factory method 'setLdapTemplate' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
... 32 more
Caused by: java.lang.NullPointerException
at test.SubBean.setLdapTemplate(SubBean.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 33 more
This is because this.string isn't set at int separatorLocation = this.string.indexOf('/', 8); in SubBean.java. I would need to be able to set string in a constructor (which Spring doesn't allow in managed beans) or autowire ldapTemplate after I've set the object properties manually.
Do not use #Bean in a #Service class. #Bean methods belong in #Configuration classes.
Move the method, so it can be called before Spring tries to autowire the ldapTemplate field.

Getting Exception while creating beans using #Bean Spring annotation

I was trying to understand difference between #component and #Bean in Spring framework, and referred to this SO question.
Based on the answer, I got a fair understanding, and tried to reinforce the concept by implementing a simple example (to check whether I really understood the concept).
The below is the code which I wrote. I wanted to see #Bean for "third party" libs (so that it can be instantiated using #Bean annotation)
package com.example.thirdparty.code;
public class ThirdPartyUtil {
public ThirdPartyUtil() {
}
public void print(String str) {
System.out.println("String passed is --> " + str);
}
}
In above, I tried to simulate a "third party lib/class - NON spring" which isn't a spring based (and so there won't be any #component in that class.
Now, below is the main application which I created:
package com.example.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import com.example.thirdparty.code.ThirdPartyUtil;
#Configuration
#ComponentScan(basePackages = { "com.example.spring" })
#Component
public class SpringBasedMainApp {
#Autowired
private ApplicationContext ctx;
#Autowired
private static ThirdPartyUtil thirdPartyUtil;
#Bean
public ThirdPartyUtil beanThirdPartyUtil() {
try {
Class c = getClass().getClassLoader().loadClass("com.example.thirdparty.code.ThirdPartyUtil");
return (ThirdPartyUtil) ctx.getBean(c);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Exception");
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringBasedMainApp.class);
System.out.println("thirdPartyUtil is " + thirdPartyUtil);
}
}
I was hoping that using #Bean annotation, it would create ThirdPartyUtil as Spring bean, and then inject using #Autowired into field thirdPartyUtil.
However, when I run this program, I got altogether a surprising exception, listed below:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanThirdPartyUtil' defined in com.example.spring.SpringBasedMainApp: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.thirdparty.code.ThirdPartyUtil]: Factory method 'beanThirdPartyUtil' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanThirdPartyUtil': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:88)
at com.example.spring.SpringBasedMainApp.main(SpringBasedMainApp.java:41)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.thirdparty.code.ThirdPartyUtil]: Factory method 'beanThirdPartyUtil' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanThirdPartyUtil': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622)
... 14 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanThirdPartyUtil': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:215)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:224)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1112)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:407)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:341)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1101)
at com.example.spring.SpringBasedMainApp.beanThirdPartyUtil(SpringBasedMainApp.java:33)
at com.example.spring.SpringBasedMainApp$$EnhancerBySpringCGLIB$$d93c67f4.CGLIB$beanThirdPartyUtil$0(<generated>)
at com.example.spring.SpringBasedMainApp$$EnhancerBySpringCGLIB$$d93c67f4$$FastClassBySpringCGLIB$$9349d69b.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at com.example.spring.SpringBasedMainApp$$EnhancerBySpringCGLIB$$d93c67f4.beanThirdPartyUtil(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 15 more
I didn't understand why it is giving this exception. I am creating an applicationContext using AnnotationConfigApplicationContext and passing the necessary details to it.
I expected it to work, however got the above exception (which I have seen maiden time).
Why has this exception been thrown, is my understanding not correct about #Bean?
The goal of the #Bean annotation is to annotate a method whose responsibility is to create an object, that will then be registered as a bean by Spring.
But inside your method, you ask Spring (using ctx.getBean()) to give you the bean that you're currently creating. So you get that exception.
Here's what your methd should look like:
#Bean
public ThirdPartyUtil beanThirdPartyUtil() {
return new ThirdPartyUtil();
}
To extend #JB Nizet answer, instantiate your third party class in spring constructor like below.
#Autowired
private static ThirdPartyUtil thirdPartyUtil;
#Autowired
public SpringBean() {
this.thirdPartyUtil = new ThirdPartyUtil();
}

Error creating bean with name 'projectingArgumentResolverBeanPostProcessor'

Im setting my web security in my project , but i see an error.
this is the error
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'projectingArgumentResolverBeanPostProcessor'
defined in class path resource
[org/springframework/data/web/config/ProjectingArgumentResolverRegistrar.class]:
BeanPostProcessor before instantiation of bean failed; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'metaDataSourceAdvisor': Cannot resolve
reference to bean 'methodSecurityMetadataSource' while setting
constructor argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'methodSecurityMetadataSource' defined in
class path resource
[org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.security.access.method.MethodSecurityMetadataSource]:
Factory method 'methodSecurityMetadataSource' threw exception; nested
exception is java.lang.IllegalStateException: In the composition of
all global method configuration, no annotation support was actually
activated at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:510)
~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:240)
~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:721)
~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:534)
~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE] at
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE] at
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE] at
org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE] at
com.supermarket.SupermarketApplication.main(SupermarketApplication.java:19)
[classes/:na]
my cod is :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private Environment env;
#Autowired
private UserSecurityService usersecurityservice;
private BCryptPasswordEncoder passwordencoder(){
return SecurityUtility.passwordEncoder();
}
private static final String[]PUBLIC_MATCHES = {
"/css/**",
"/js/**",
"/img/**",
"/signUp",
"/",
"/newUser",
"/forgetPassword",
"/login",
"/fonts/**",
"/bookshelf/**",
"/bookDetail/**",
"/hours",
"/faq",
"/searchByCategory",
"/searchBook"
};
#Override
protected void configure(HttpSecurity http)throws Exception{
http
.authorizeRequests().
/*antMatchers("/**").*/
antMatchers(PUBLIC_MATCHES).
permitAll().anyRequest().authenticated();
http
.csrf().disable().cors().disable()
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.successForwardUrl("/login")
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
.and()
.rememberMe();
}
#Autowired
public void configureGlobal (AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(usersecurityservice).passwordEncoder(passwordencoder());
}
}
userSecurity class is:
#Service
public class UserSecurityService implements UserDetailsService {
#Autowired()
private UserRepository userRepository;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
try{
}catch(Exception ex){
System.out.println("Error acoured hear:");
}
User user=userRepository.findByUsername(username);
if(null==user){
throw new UsernameNotFoundException("Username not found");
}
return user;
}
When i delete '#EnableGlobalMethodSecurity' annotation program run correctly
I had used this cod before and it worked correctly.
Did you update spring recently? In previous versions it was ok to have a null MethodSecurityMetadataSource, but now they added this check where if you don't have at least one method security metadata source enabled, they throw the exception that you are getting ("In the composition of all global method configuration, no annotation support was actually activated"). This happened to me when I updated from spring 5.0.7 to 5.1.5. Here is the issue where this change was discussed
To fix it, either enable one of the metadata sources in the #EnableGlobalMethodSecurity annotation properties, or, if like me, you are using some kind of GlobalMethodSecurityConfiguration, make sure the method customMethodSecurityMetadataSource returns not-null
You are having this issue because you have not annotation correctly. You should add it like this: #EnableGlobalMethodSecurity(prePostEnabled = true)

Problems with Spring Java Config and #EnableTransactionManagement

I am migrating away from XML config for Spring context configuration. Instead when I try to use the functionally equivalent #EnableTransactionManagement on a Spring 4.0.3.RELEASE Java Configuration, my Spring context fails to instantiate with the following exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:236)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:134)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseMySQLTest.TestConfig': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.intercep...skipping...
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 45 more
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
... 62 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:324)
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.transactionInterceptor()
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor(ProxyTransactionManagementConfiguration.java:45)
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.CGLIB$transactionAdvisor$0()
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634$$FastClassBySpringCGLIB$$cc829ae.invoke()
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.transactionAdvisor()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 63 more
Caused by: java.lang.IllegalArgumentException: Property 'transactionManager' is required
at org.springframework.transaction.interceptor.TransactionAspectSupport.afterPropertiesSet(TransactionAspectSupport.java:195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 82 more
This happens to obtain in a unit test, but when it works here, I can use it in production code.
Here is my unit test base class where the Spring wiring occurs:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {PropertyPlaceholderConfigurer.class, BaseMySQLTest.TestConfig.class})
public class BaseMySQLTest extends AbstractTransactionalJUnit4SpringContextTests {
#Configuration
#Import(DaoConfig.class)
#PropertySource("classpath:/jdbc.properties")
#EnableTransactionManagement
public static class TestConfig {
#Bean
public PlatformTransactionManager providesTransactionManager(ListableBeanFactory beanFactory) {
return new DataSourceTransactionManager(beanFactory.getBean(DataSource.class));
}
}
}
and here is a subclass that uses this base class and config:
public class UserDaoImplTest extends BaseMySQLTest {
#Autowired
private UserDao userDao;
#Test
public void testById() throws Exception {
jdbcTemplate.execute("insert into users (email) values ('bob#example.com')");
...
}
}
As one can see, my Spring TestConfig has a transaction manager bean defined, which according to the Javadoc
http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html
means I do not have to name the bean (though I have named it in an attempt to get this to work). In fact, the Spring context is behaving as if configured with XML config in the face of no bean explicitly named "transactionManager".
What is my Java Config missing such that the Spring context cannot use this transaction manager bean to satisfy its requirements at instantiation time?
Thank you for any helpful observations.
EDIT:
(I'm not sure where this edit should go, so I try here. ae6rt)
Here is the new test class, which results in the same error as the original work:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {BaseMySQLTest.TestConfig.class})
public class BaseMySQLTest extends AbstractTransactionalJUnit4SpringContextTests {
protected int lastInsertId() {
return jdbcTemplate.queryForInt("select LAST_INSERT_ID()");
}
#Autowired
private UserDao userDao;
#Test
public void testById() throws Exception {
jdbcTemplate.execute("insert into mgdb.users (email) values ('bob#example.com')");
int userId = lastInsertId();
Optional xoomUserOptional = userDao.byId(userId);
assertThat(xoomUserOptional.isPresent(), equalTo(true));
XoomUser user = xoomUserOptional.get();
assertThat(user.getEmailAddress(), equalTo("bob#example.com"));
}
#Configuration
#Import(DaoConfig.class)
#PropertySource("classpath:/jdbc.properties")
#EnableTransactionManagement
public static class TestConfig {
#Bean
public PlatformTransactionManager providesTransactionManager(ListableBeanFactory beanFactory) {
return new DataSourceTransactionManager(beanFactory.getBean(DataSource.class));
}
}
}
I didn't actualy need the property config here
#ContextConfiguration(classes = {BaseMySQLTest.TestConfig.class})
so I removed it. Hope this meets the spirit of this round.
Looks like the only change should be to name your transaction manager bean name to "transactionManager":
public static class TestConfig {
#Autowired
private DataSource datasource;
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(datasource);
}
}
EDIT :
Can you try these additional things:
.1. Remove PropertyPlaceHolderConfigurer from here.. #ContextConfiguration(classes = {PropertyPlaceholderConfigurer.class, BaseMySQLTest.TestConfig.class}), that is not how PropertyPlaceholderConfigurer is used, you have to do it this way:
#Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer();
ClassPathResource resource = new ClassPathResource("/META-INF/spring/database.properties");
placeholderConfigurer.setLocation(resource);
return placeholderConfigurer;
}
Also, just for test, can you move your actual test to the base class also and see if one of these configuration works out for you. I tested in my own machine and it seems to work nicely with Spring 4.0.2+.

Categories