While migrating older Spring 2.5 code to Spring 3.2 I also changed the configuration from xml to java. This is not finished yet, because I don't want to change the web.xml for the moment.
But when trying to start the code (on Java 8) I got an exception for which I can't find a solution at the moment:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource' defined in class path resource [com/tms/core/configuration/TMSApplicationConfig.class]: Initialization of bean failed
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot resolve reference to bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' while setting bean property 'transactionAttributeSource'
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0': BeanPostProcessor before instantiation of bean failed
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exLoggerAdvisor' defined in class path resource [com/tms/core/configuration/TMSApplicationConfig.class]: Instantiation of bean failed
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.aop.Advisor com.tms.core.configuration.TMSApplicationConfig.exLoggerAdvisor()] threw exception
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exLoggerInterceptor' defined in class path resource [com/tms/core/configuration/TMSApplicationConfig.class]: Instantiation of bean failed
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public util.ExceptionLogInterceptor com.tms.core.configuration.TMSApplicationConfig.exLoggerInterceptor()] threw exception
Caused by: java.lang.NullPointerException
at com.tms.core.configuration.TMSApplicationConfig.exLoggerInterceptor(TMSApplicationConfig.java:2397) ~[classes/:?]
The NullPointerException is clear to me, because it looks like the Environment of my config class is not initialized:
package com.tms.core.configuration;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.tms.core")
@ImportResource({"classpath:mailContext.xml", "classpath:pluginsContext.xml", "classpath:replicationContext.xml"})
@EnableSolrRepositories("com.tms.core.model.solr.repositories")
@EnableTransactionManagement(order = 35)
@PropertySource({"classpath:applicationContext.properties", "classpath:allowedContentTypes.properties"})
public class TMSApplicationConfig
{
// @Inject
@Autowired(required = true)
private Environment env;
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfig()
{
final PropertySourcesPlaceholderConfigurer pspconf = new PropertySourcesPlaceholderConfigurer();
pspconf.setFileEncoding(StandardCharsets.UTF_8.name());
pspconf.setPropertiesPersister(new EncryptedPropertiesReader());
return pspconf;
}
@Bean
public MessageSource messageSource()
{
final ReloadableResourceBundleMessageSource rrbms = new ReloadableResourceBundleMessageSource();
rrbms.setBasenames("classpath:/tms-messages", "classpath:/tms-labels");
rrbms.setCacheSeconds(1);
rrbms.setUseCodeAsDefaultMessage(true);
rrbms.setFallbackToSystemLocale(false);
rrbms.setDefaultEncoding(StandardCharsets.UTF_8.name());
return rrbms;
}
@Bean
public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor()
{
return new PersistenceAnnotationBeanPostProcessor();
}
@Bean
public RequiredAnnotationBeanPostProcessor requiredAnnotationBeanPostProcessor()
{
return new RequiredAnnotationBeanPostProcessor();
}
@Pointcut("execution (* com.tms..*.*(..)) and !execution (* com.tms.core.service.LBHttpSolrServer.*(..)) and !execution(* com.tms.core.configuration..*.*(..))")
public void exLoggerPointcut()
{
}
@Bean
public ExceptionLogInterceptor exLoggerInterceptor()
{
final ExceptionLogInterceptor interceptor = new ExceptionLogInterceptor();
interceptor.setUseDynamicLogger(true);
interceptor.setHideProxyClassNames(true);
interceptor.setLogAlways(Boolean.parseBoolean(this.env.getProperty("log.errorLogAlways"))); // this.env is null here!
return interceptor;
}
@Bean
public Advisor exLoggerAdvisor()
{
final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("com.tms.core.configuration.TMSApplicationConfig.exLoggerPointcut()");
final DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, exLoggerInterceptor());
advisor.setOrder(10);
return advisor;
}
// Removed all other beans!
}
For the case that it is important - I am starting still in an old way via applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:component-scan base-package="com.tms.core.configuration" />
<mvc:annotation-driven />
<tx:annotation-driven />
</beans>
Some things might be happen twice at the moment, but this is not the point, because the code transformation has not been finished yet.
My question is, how could I resolve the Exception? Which leads to the question why is the environment not initialized? Looks a bit like a Hen/Egg problem.
What is not clear to me are the exception parts about internalTransactionAdvisor and AnnotationTransactionAttributeSource.
I transformed the xml configuration to java as good as I could, but maybe I made a mistake by transforming the aop advises?
<bean id="exLoggerInterceptor" class="util.ExceptionLogInterceptor" p:useDynamicLogger="true" p:hideProxyClassNames="true" p:log-always="${log.errorLogAlways}" />
<aop:advisor advice-ref="exLoggerInterceptor" order="10" pointcut="execution (* com.tms..*.*(..)) and !execution (* com.tms.core.service.LBHttpSolrServer.*(..))" />
Update 1:
Adding !execution(* com.tms.core.configuration..*.*(..)) to the pointcut seems not to fix a possible Hen/Egg problem.
Update 2:
After replacing every this.env.getProperty() call with a static value I got an
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context
Which makes the whole thing a much bigger problem :(