diff --git a/pom.xml b/pom.xml
index 9792a3308..1db9b70eb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -270,7 +270,7 @@
test-process
- ${project.build.directory}/generated-sources/test-annotations
+ ${project.build.directory}/generated-test-sources/test-annotations
com.querydsl.apt.QuerydslAnnotationProcessor
diff --git a/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java b/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java
index b5b8f9acf..d1c3fda1e 100644
--- a/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java
+++ b/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java
@@ -78,15 +78,22 @@ public @interface EnableSpringDataWebSupport {
* https://jira.springsource.org/browse/SPR-10565).
*
* @author Oliver Gierke
+ * @author Jens Schauder
*/
static class SpringDataWebConfigurationImportSelector implements ImportSelector, ResourceLoaderAware {
- // Don't make final to allow test cases faking this to false
- private static boolean HATEOAS_PRESENT = ClassUtils.isPresent("org.springframework.hateoas.Link", null);
- private static boolean JACKSON_PRESENT = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null);
-
+ private Environment environment;
private ResourceLoader resourceLoader;
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.context.EnvironmentAware#setEnvironment(org.springframework.core.env.Environment)
+ */
+ @Override
+ public void setEnvironment(Environment environment) {
+ this.environment = environment;
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
@@ -105,10 +112,11 @@ public @interface EnableSpringDataWebSupport {
List imports = new ArrayList<>();
- imports.add(HATEOAS_PRESENT ? HateoasAwareSpringDataWebConfiguration.class.getName()
+ imports.add(ClassUtils.isPresent("org.springframework.hateoas.Link", resourceLoader.getClassLoader())
+ ? HateoasAwareSpringDataWebConfiguration.class.getName()
: SpringDataWebConfiguration.class.getName());
- if (JACKSON_PRESENT) {
+ if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", resourceLoader.getClassLoader())) {
imports.addAll(
SpringFactoriesLoader.loadFactoryNames(SpringDataJacksonModules.class, resourceLoader.getClassLoader()));
}
diff --git a/src/test/java/org/springframework/data/classloadersupport/ClassLoaderConfiguration.java b/src/test/java/org/springframework/data/classloadersupport/ClassLoaderConfiguration.java
new file mode 100644
index 000000000..731487413
--- /dev/null
+++ b/src/test/java/org/springframework/data/classloadersupport/ClassLoaderConfiguration.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.classloadersupport;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * configures the {@link ClassLoaderRule}.
+ *
+ * @author Jens Schauder
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ClassLoaderConfiguration {
+
+ /**
+ * classes of which the package that contains them will be loaded by the {@link HidingClassLoader} not by
+ * the normal {@code ClassLoader}.
+ *
+ * @return list of classes not to shadow.
+ */
+ Class[] shadowPackage() default {};
+
+ /**
+ * prefixes of class names that will be loaded by the {@link HidingClassLoader}.
+ *
+ * @return list of class prefixes which will not be shadowed.
+ */
+ String[] shadowByPrefix() default {};
+
+ /**
+ * classes of which the package that contains them will be hidden by the {@link HidingClassLoader}.
+ *
+ * @return list of classes to hidePackage.
+ */
+ Class[] hidePackage() default {};
+
+ /**
+ * classes from packages that will be hidden by the {@link HidingClassLoader}.
+ *
+ * @return list of classes of which the package will be hidden.
+ */
+ String[] hideByPrefix() default {};
+}
diff --git a/src/test/java/org/springframework/data/classloadersupport/ClassLoaderRule.java b/src/test/java/org/springframework/data/classloadersupport/ClassLoaderRule.java
new file mode 100644
index 000000000..1def36324
--- /dev/null
+++ b/src/test/java/org/springframework/data/classloadersupport/ClassLoaderRule.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.classloadersupport;
+
+import static java.util.Arrays.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * supports creation of tests that need to load classes with a {@link HidingClassLoader}.
+ *
+ * @author Jens Schauder
+ */
+public class ClassLoaderRule implements MethodRule {
+
+ public HidingClassLoader classLoader;
+
+ @Override
+ public Statement apply(final Statement base, FrameworkMethod method, Object target) {
+
+ CombinedClassLoaderConfiguration combinedConfiguration = new CombinedClassLoaderConfiguration(
+ method.getAnnotation(ClassLoaderConfiguration.class),
+ method.getDeclaringClass().getAnnotation(ClassLoaderConfiguration.class)
+ );
+
+ classLoader = createClassLoader(combinedConfiguration);
+
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+
+ try {
+ base.evaluate();
+ } finally {
+ classLoader = null;
+ }
+ }
+ };
+ }
+
+ private static HidingClassLoader createClassLoader(CombinedClassLoaderConfiguration configuration) {
+
+ HidingClassLoader classLoader = new HidingClassLoader(mergeHidden(configuration));
+
+ for (Class shadow : configuration.shadowPackages) {
+ classLoader.excludeClass(shadow.getPackage().getName());
+ }
+
+ for (String shadow : configuration.shadowByPrefix) {
+ classLoader.excludePackage(shadow);
+ }
+
+ return classLoader;
+ }
+
+ private static List mergeHidden(CombinedClassLoaderConfiguration configuration) {
+
+ List hidden = new ArrayList();
+
+ for (Class aClass : configuration.hidePackages) {
+ hidden.add(aClass.getPackage().getName());
+ }
+
+ for (String aPackage : configuration.hideByPrefix) {
+ hidden.add(aPackage);
+ }
+
+ return hidden;
+ }
+
+ private static class CombinedClassLoaderConfiguration {
+
+ final List shadowPackages = new ArrayList();
+ final List shadowByPrefix = new ArrayList();
+ final List hidePackages = new ArrayList();
+ final List hideByPrefix = new ArrayList();
+
+ CombinedClassLoaderConfiguration(ClassLoaderConfiguration methodAnnotation, ClassLoaderConfiguration classAnnotation) {
+
+ mergeAnnotation(methodAnnotation);
+ mergeAnnotation(classAnnotation);
+ }
+
+ private void mergeAnnotation(ClassLoaderConfiguration methodAnnotation) {
+
+ if (methodAnnotation != null) {
+
+ shadowPackages.addAll(asList(methodAnnotation.shadowPackage()));
+ shadowByPrefix.addAll(asList(methodAnnotation.shadowByPrefix()));
+ hidePackages.addAll(asList(methodAnnotation.hidePackage()));
+ hideByPrefix.addAll(asList(methodAnnotation.hideByPrefix()));
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/springframework/data/classloadersupport/HidingClassLoader.java b/src/test/java/org/springframework/data/classloadersupport/HidingClassLoader.java
new file mode 100644
index 000000000..27e5ca46b
--- /dev/null
+++ b/src/test/java/org/springframework/data/classloadersupport/HidingClassLoader.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.classloadersupport;
+
+import java.net.URLClassLoader;
+import java.util.Collection;
+
+/**
+ * is intended for testing code that depends on the presence/absence of certain classes.
+ *
+ * Classes can be:
+ *
+ * - shadowed: reloaded by this classloader no matter if they are loaded already by the SystemClassLoader
+ * - hidden: not loaded by this classloader no matter if they are loaded already by the SystemClassLoader. Trying to load these classes results in a {@link ClassNotFoundException}
+ * - all other classes get loaded by the SystemClassLoader
+ *
+ *
+ * @author Jens Schauder
+ */
+public class HidingClassLoader extends ShadowingClassLoader {
+
+ private final Collection hidden;
+
+ HidingClassLoader(Collection hidden) {
+ super(URLClassLoader.getSystemClassLoader());
+ this.hidden = hidden;
+ }
+
+ @Override
+ public Class> loadClass(String name) throws ClassNotFoundException {
+
+ checkIfHidden(name);
+ return super.loadClass(name);
+ }
+
+ @Override
+ protected Class> findClass(String name) throws ClassNotFoundException {
+
+ checkIfHidden(name);
+ return super.findClass(name);
+ }
+
+ private void checkIfHidden(String name) throws ClassNotFoundException {
+
+ for (String prefix : hidden) {
+ if (name.startsWith(prefix)) {
+ throw new ClassNotFoundException();
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/springframework/data/classloadersupport/ShadowingClassLoader.java b/src/test/java/org/springframework/data/classloadersupport/ShadowingClassLoader.java
new file mode 100644
index 000000000..6011f424b
--- /dev/null
+++ b/src/test/java/org/springframework/data/classloadersupport/ShadowingClassLoader.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2002-2012 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.data.classloadersupport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.core.DecoratingClassLoader;
+import org.springframework.util.Assert;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * ClassLoader decorator that shadows an enclosing ClassLoader,
+ * applying registered transformers to all affected classes.
+ *
+ * @author Rob Harrop
+ * @author Juergen Hoeller
+ * @author Costin Leau
+ * @since 2.0
+ * @see #addTransformer
+ * @see org.springframework.core.OverridingClassLoader
+ */
+public class ShadowingClassLoader extends DecoratingClassLoader {
+
+ /** Packages that are excluded by default */
+ public static final String[] DEFAULT_EXCLUDED_PACKAGES =
+ new String[] {"java.", "javax.", "sun.", "oracle.", "com.sun.", "com.ibm.", "COM.ibm.",
+ "org.w3c.", "org.xml.", "org.dom4j.", "org.eclipse", "org.aspectj.", "net.sf.cglib",
+ "org.springframework.cglib", "org.apache.xerces.", "org.apache.commons.logging."};
+
+
+ private final ClassLoader enclosingClassLoader;
+
+ private final List classFileTransformers = new LinkedList();
+
+ private final Map> classCache = new HashMap>();
+
+
+ /**
+ * Create a new ShadowingClassLoader, decorating the given ClassLoader.
+ * @param enclosingClassLoader the ClassLoader to decorate
+ */
+ public ShadowingClassLoader(ClassLoader enclosingClassLoader) {
+ Assert.notNull(enclosingClassLoader, "Enclosing ClassLoader must not be null");
+ this.enclosingClassLoader = enclosingClassLoader;
+ }
+
+
+ /**
+ * Add the given ClassFileTransformer to the list of transformers that this
+ * ClassLoader will apply.
+ * @param transformer the ClassFileTransformer
+ */
+ public void addTransformer(ClassFileTransformer transformer) {
+ Assert.notNull(transformer, "Transformer must not be null");
+ this.classFileTransformers.add(transformer);
+ }
+
+ /**
+ * Copy all ClassFileTransformers from the given ClassLoader to the list of
+ * transformers that this ClassLoader will apply.
+ * @param other the ClassLoader to copy from
+ */
+ public void copyTransformers(ShadowingClassLoader other) {
+ Assert.notNull(other, "Other ClassLoader must not be null");
+ this.classFileTransformers.addAll(other.classFileTransformers);
+ }
+
+
+ @Override
+ public Class> loadClass(String name) throws ClassNotFoundException {
+ if (shouldShadow(name)) {
+ System.out.println("shadowing " + name);
+ Class> cls = this.classCache.get(name);
+ if (cls != null) {
+ return cls;
+ }
+ return doLoadClass(name);
+ }
+ else {
+ return this.enclosingClassLoader.loadClass(name);
+ }
+ }
+
+ /**
+ * Determine whether the given class should be excluded from shadowing.
+ * @param className the name of the class
+ * @return whether the specified class should be shadowed
+ */
+ private boolean shouldShadow(String className) {
+ return (!className.equals(getClass().getName()) && !className.endsWith("ShadowingClassLoader") &&
+ isEligibleForShadowing(className));
+ }
+
+ /**
+ * Determine whether the specified class is eligible for shadowing
+ * by this class loader.
+ * @param className the class name to check
+ * @return whether the specified class is eligible
+ * @see #isExcluded
+ */
+ protected boolean isEligibleForShadowing(String className) {
+ return isExcluded(className);
+ }
+
+
+ private Class> doLoadClass(String name) throws ClassNotFoundException {
+ String internalName = StringUtils.replace(name, ".", "/") + ".class";
+ InputStream is = this.enclosingClassLoader.getResourceAsStream(internalName);
+ if (is == null) {
+ throw new ClassNotFoundException(name);
+ }
+ try {
+ byte[] bytes = FileCopyUtils.copyToByteArray(is);
+ bytes = applyTransformers(name, bytes);
+ Class> cls = defineClass(name, bytes, 0, bytes.length);
+ // Additional check for defining the package, if not defined yet.
+ if (cls.getPackage() == null) {
+ int packageSeparator = name.lastIndexOf('.');
+ if (packageSeparator != -1) {
+ String packageName = name.substring(0, packageSeparator);
+ definePackage(packageName, null, null, null, null, null, null, null);
+ }
+ }
+ this.classCache.put(name, cls);
+ return cls;
+ }
+ catch (IOException ex) {
+ throw new ClassNotFoundException("Cannot load resource for class [" + name + "]", ex);
+ }
+ }
+
+ private byte[] applyTransformers(String name, byte[] bytes) {
+ String internalName = StringUtils.replace(name, ".", "/");
+ try {
+ for (ClassFileTransformer transformer : this.classFileTransformers) {
+ byte[] transformed = transformer.transform(this, internalName, null, null, bytes);
+ bytes = (transformed != null ? transformed : bytes);
+ }
+ return bytes;
+ }
+ catch (IllegalClassFormatException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+
+ @Override
+ public URL getResource(String name) {
+ return this.enclosingClassLoader.getResource(name);
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String name) {
+ return this.enclosingClassLoader.getResourceAsStream(name);
+ }
+
+ @Override
+ public Enumeration getResources(String name) throws IOException {
+ return this.enclosingClassLoader.getResources(name);
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/web/WebTestUtils.java b/src/test/java/org/springframework/data/web/WebTestUtils.java
index 2c8c6a0df..58fcbef4d 100644
--- a/src/test/java/org/springframework/data/web/WebTestUtils.java
+++ b/src/test/java/org/springframework/data/web/WebTestUtils.java
@@ -24,7 +24,7 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
/**
* Helper methods for web integration testing.
- *
+ *
* @author Oliver Gierke
*/
public class WebTestUtils {
@@ -41,13 +41,28 @@ public class WebTestUtils {
/**
* Creates a {@link WebApplicationContext} from the given configuration classes.
- *
+ *
* @param configClasses
* @return
*/
public static WebApplicationContext createApplicationContext(Class>... configClasses) {
+ return createApplicationContext(null, configClasses);
+ }
+
+ /**
+ * Creates a {@link WebApplicationContext} from the given configuration classes.
+ *
+ * @param classLoader gets set as ClassLoader in the context
+ * @param configClasses
+ * @return
+ */
+ public static WebApplicationContext createApplicationContext(ClassLoader classLoader, Class>... configClasses) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+ if (classLoader != null) {
+ context.setClassLoader(classLoader);
+ }
+
context.setServletContext(new MockServletContext());
for (Class> configClass : configClasses) {
diff --git a/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java b/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java
index e78e736cb..13a2d0311 100755
--- a/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java
+++ b/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java
@@ -20,56 +20,62 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.lang.reflect.Field;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-
-import org.junit.After;
+import org.hamcrest.Matcher;
+import org.junit.Rule;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
+import org.springframework.data.classloadersupport.ClassLoaderConfiguration;
+import org.springframework.data.classloadersupport.ClassLoaderRule;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.data.web.PagedResourcesAssemblerArgumentResolver;
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
import org.springframework.data.web.WebTestUtils;
-import org.springframework.data.web.config.EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector;
+import org.springframework.hateoas.Link;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.util.ReflectionUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.util.UriComponentsBuilder;
/**
* Integration tests for {@link EnableSpringDataWebSupport}.
- *
+ *
* @author Oliver Gierke
+ * @author Jens Schauder
*/
+
+@ClassLoaderConfiguration(shadowPackage = {
+ WebMvcConfigurationSupport.class,
+ EnableSpringDataWebSupport.class,
+ EnableSpringDataWebSupportIntegrationTests.SampleConfig.class})
public class EnableSpringDataWebSupportIntegrationTests {
- private static final String HATEOAS = "HATEOAS_PRESENT";
- private static final String JACKSON = "JACKSON_PRESENT";
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
static class SampleConfig {
- public @Bean SampleController controller() {
+ public
+ @Bean
+ SampleController controller() {
return new SampleController();
}
}
- @After
- public void tearDown() {
- reEnable(HATEOAS);
- reEnable(JACKSON);
- }
+ @Rule public ClassLoaderRule classLoaderRule = new ClassLoaderRule();
+
@Test // DATACMNS-330
public void registersBasicBeanDefinitions() throws Exception {
@@ -94,11 +100,11 @@ public class EnableSpringDataWebSupportIntegrationTests {
}
@Test // DATACMNS-330
+ @ClassLoaderConfiguration(hidePackage = Link.class)
public void doesNotRegisterHateoasSpecificComponentsIfHateoasNotPresent() throws Exception {
- hide(HATEOAS);
+ ApplicationContext context = WebTestUtils.createApplicationContext(classLoaderRule.classLoader, SampleConfig.class);
- ApplicationContext context = WebTestUtils.createApplicationContext(SampleConfig.class);
List names = Arrays.asList(context.getBeanDefinitionNames());
assertThat(names).contains("pageableResolver", "sortResolver");
@@ -115,11 +121,11 @@ public class EnableSpringDataWebSupportIntegrationTests {
}
@Test // DATACMNS-475
+ @ClassLoaderConfiguration(hidePackage = com.fasterxml.jackson.databind.ObjectMapper.class)
public void doesNotRegisterJacksonSpecificComponentsIfJacksonNotPresent() throws Exception {
- hide(JACKSON);
+ ApplicationContext context = WebTestUtils.createApplicationContext(classLoaderRule.classLoader, SampleConfig.class);
- ApplicationContext context = WebTestUtils.createApplicationContext(SampleConfig.class);
List names = Arrays.asList(context.getBeanDefinitionNames());
assertThat(names).doesNotContain("jacksonGeoModule");
@@ -173,18 +179,4 @@ public class EnableSpringDataWebSupportIntegrationTests {
Arrays.asList(resolverTypes).forEach(type -> assertThat(resolvers).hasAtLeastOneElementOfType(type));
}
-
- private static void hide(String module) throws Exception {
-
- Field field = ReflectionUtils.findField(SpringDataWebConfigurationImportSelector.class, module);
- ReflectionUtils.makeAccessible(field);
- ReflectionUtils.setField(field, null, false);
- }
-
- private static void reEnable(String module) {
-
- Field field = ReflectionUtils.findField(SpringDataWebConfigurationImportSelector.class, module);
- ReflectionUtils.makeAccessible(field);
- ReflectionUtils.setField(field, null, true);
- }
}
diff --git a/src/test/java/org/springframework/data/web/config/SpringDataWebConfigurationIntegrationTests.java b/src/test/java/org/springframework/data/web/config/SpringDataWebConfigurationIntegrationTests.java
index 06fb61432..32b5133ed 100644
--- a/src/test/java/org/springframework/data/web/config/SpringDataWebConfigurationIntegrationTests.java
+++ b/src/test/java/org/springframework/data/web/config/SpringDataWebConfigurationIntegrationTests.java
@@ -18,20 +18,17 @@ package org.springframework.data.web.config;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
-import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
-
import org.hamcrest.Matcher;
+import org.junit.Rule;
import org.junit.Test;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.core.convert.ConversionService;
+import org.springframework.data.classloadersupport.ClassLoaderConfiguration;
+import org.springframework.data.classloadersupport.ClassLoaderRule;
import org.springframework.data.web.ProjectingJackson2HttpMessageConverter;
import org.springframework.data.web.XmlBeamHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.instrument.classloading.ShadowingClassLoader;
/**
* Integration test for {@link SpringDataWebConfiguration}.
@@ -42,32 +39,37 @@ import org.springframework.instrument.classloading.ShadowingClassLoader;
*/
public class SpringDataWebConfigurationIntegrationTests {
+ @Rule public ClassLoaderRule classLoader = new ClassLoaderRule();
+
@Test // DATACMNS-987
+ @ClassLoaderConfiguration(hidePackage = com.fasterxml.jackson.databind.ObjectMapper.class)
public void shouldNotLoadJacksonConverterWhenJacksonNotPresent() {
List> converters = new ArrayList>();
- createConfigWithClassLoaderExcluding("com.fasterxml.jackson").extendMessageConverters(converters);
+ createConfigWithClassLoader().extendMessageConverters(converters);
assertThat(converters, not(hasItem(instanceWithClassName(ProjectingJackson2HttpMessageConverter.class))));
}
@Test // DATACMNS-987
+ @ClassLoaderConfiguration(hidePackage = com.jayway.jsonpath.DocumentContext.class)
public void shouldNotLoadJacksonConverterWhenJaywayNotPresent() {
List> converters = new ArrayList>();
- createConfigWithClassLoaderExcluding("com.jayway").extendMessageConverters(converters);
+ createConfigWithClassLoader().extendMessageConverters(converters);
assertThat(converters, not(hasItem(instanceWithClassName(ProjectingJackson2HttpMessageConverter.class))));
}
@Test // DATACMNS-987
+ @ClassLoaderConfiguration(hidePackage = org.xmlbeam.ProjectionFactory.class)
public void shouldNotLoadXBeamConverterWhenXBeamNotPresent() throws Exception {
List> converters = new ArrayList>();
- createConfigWithClassLoaderExcluding("org.xmlbeam").extendMessageConverters(converters);
+ createConfigWithClassLoader().extendMessageConverters(converters);
assertThat(converters, not(hasItem(instanceWithClassName(XmlBeamHttpMessageConverter.class))));
}
@@ -77,17 +79,17 @@ public class SpringDataWebConfigurationIntegrationTests {
List> converters = new ArrayList>();
- createConfigWithClassLoaderExcluding("load.everything").extendMessageConverters(converters);
+ createConfigWithClassLoader().extendMessageConverters(converters);
assertThat(converters, hasItem(instanceWithClassName(XmlBeamHttpMessageConverter.class)));
assertThat(converters, hasItem(instanceWithClassName(ProjectingJackson2HttpMessageConverter.class)));
}
- private static SpringDataWebConfiguration createConfigWithClassLoaderExcluding(String excludedClassNamePrefix) {
+ private SpringDataWebConfiguration createConfigWithClassLoader() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SpringDataWebConfiguration.class);
- context.setClassLoader(initClassLoader(excludedClassNamePrefix));
+ context.setClassLoader(classLoader.classLoader);
try {
return context.getBean(SpringDataWebConfiguration.class);
@@ -106,38 +108,4 @@ public class SpringDataWebConfigurationIntegrationTests {
private static Matcher instanceWithClassName(Class expectedClass) {
return hasProperty("class", hasProperty("name", equalTo(expectedClass.getName())));
}
-
- private static ClassLoader initClassLoader(final String excludedClassNamePrefix) {
-
- return new ShadowingClassLoader(URLClassLoader.getSystemClassLoader()) {
-
- @Override
- public Class> loadClass(String name) throws ClassNotFoundException {
-
- if (name.startsWith(excludedClassNamePrefix)) {
- throw new ClassNotFoundException();
- }
-
- return super.loadClass(name);
- }
-
- @Override
- protected Class> findClass(String name) throws ClassNotFoundException {
-
- if (name.startsWith(excludedClassNamePrefix)) {
- throw new ClassNotFoundException();
- }
-
- return super.findClass(name);
- }
- };
- }
-
- public static class ObjectFactoryImpl implements ObjectFactory {
-
- @Override
- public ConversionService getObject() throws BeansException {
- return null;
- }
- }
}