DATAJPA-367 - Issue error for missing spring-aspects.jar if auditing is enabled in xml config.

As the auditing feature requires spring-aspects.jar on the classpath we issue now check whether the jar is present - if not we issue an appropriate error message. Added appropriate note to the JPA reference doc. Added test case to AuditingBeanDefinitionParserTests to verify that a XMLParserError message is emitted if the required class from spring-aspects is not on the class path.

Original pull request: #34.
This commit is contained in:
Thomas Darimont
2013-08-08 19:16:48 +02:00
committed by Oliver Gierke
parent 33546db94a
commit 1c01a56690
3 changed files with 32 additions and 1 deletions

View File

@@ -1010,6 +1010,8 @@ public interface UserRepository extends JpaRepository<User, Long> {
<filename>orm.xml</filename> to be used for all entities in your
persistence contexts:</para>
<para>Note that the auditing feature requires <code>spring-aspects.jar</code> to be on the classpath.</para>
<example>
<title>Auditing configuration orm.xml</title>

View File

@@ -25,6 +25,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.config.AuditingHandlerBeanDefinitionParser;
import org.springframework.util.ClassUtils;
import org.w3c.dom.Element;
/**
@@ -88,6 +89,14 @@ public class AuditingBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
if (!ClassUtils.isPresent(BEAN_CONFIGURER_ASPECT_CLASS_NAME, getClass().getClassLoader())) {
parserContext.getReaderContext().error(
"Could not configure Spring Data JPA auditing-feature because"
+ " spring-aspects.jar is not on the classpath!\n"
+ "If you want to use auditing please add spring-aspects.jar to the classpath.", element);
}
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(BEAN_CONFIGURER_ASPECT_CLASS_NAME);
def.setFactoryMethodName("aspectOf");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2012 the original author or authors.
* Copyright 2008-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,14 +23,17 @@ import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.instrument.classloading.ShadowingClassLoader;
/**
* Integration tests for {@link AuditingBeanDefinitionParser}.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
public class AuditingBeanDefinitionParserTests {
@@ -65,6 +68,17 @@ public class AuditingBeanDefinitionParserTests {
assertThat(bean, is(notNullValue()));
}
/**
* @see DATAJPA-367
*/
@Test(expected = BeanDefinitionParsingException.class)
public void shouldThrowBeanDefinitionParsingExceptionIfClassFromSpringAspectsJarCannotBeFound() {
ShadowingClassLoader scl = new ShadowingClassLoader(getClass().getClassLoader());
scl.excludeClass(AuditingBeanDefinitionParser.AUDITING_ENTITY_LISTENER_CLASS_NAME);
DefaultListableBeanFactory factory = loadFactoryFrom("auditing/auditing-namespace-context.xml", scl);
}
private void assertSetDatesIsSetTo(String configFile, String value) {
BeanDefinition definition = getBeanDefinition(configFile);
@@ -82,6 +96,12 @@ public class AuditingBeanDefinitionParserTests {
}
private DefaultListableBeanFactory loadFactoryFrom(String configFile) {
return loadFactoryFrom(configFile, getClass().getClassLoader());
}
private DefaultListableBeanFactory loadFactoryFrom(String configFile, ClassLoader classLoader) {
Thread.currentThread().setContextClassLoader(classLoader);
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource(configFile));