From 1c01a566907531ec0f2860a5754edfa36f898e06 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Thu, 8 Aug 2013 19:16:48 +0200 Subject: [PATCH] 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. --- src/docbkx/jpa.xml | 2 ++ .../config/AuditingBeanDefinitionParser.java | 9 ++++++++ .../AuditingBeanDefinitionParserTests.java | 22 ++++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/docbkx/jpa.xml b/src/docbkx/jpa.xml index 04be97b91..a38b23bdc 100644 --- a/src/docbkx/jpa.xml +++ b/src/docbkx/jpa.xml @@ -1010,6 +1010,8 @@ public interface UserRepository extends JpaRepository<User, Long> { orm.xml to be used for all entities in your persistence contexts: + Note that the auditing feature requires spring-aspects.jar to be on the classpath. + Auditing configuration orm.xml diff --git a/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java b/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java index c797d895d..2917ae065 100644 --- a/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java @@ -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"); diff --git a/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java b/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java index 4b5ce4201..1e89e75ac 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java @@ -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));