Commit e04ace89 authored by Andy Wilkinson's avatar Andy Wilkinson

Fix LinkageError with ExpectedException and FilteredClassPathRunner

Previously, when the ExpectedException JUnit rule was used with
FilteredClassPathRunner a LinkageError would occur if any of
ExpectedException's methods that take a Hamcrest Matcher were called.
This was due to the FilteredClassLoader delegating loading of
org.junit classes to its parent but not org.hamcrest classes. This
resulted in JUnit classes loading one version of the Hamcrest class
and the test class loading another.

This commit ensures that both the JUnit classes and the test class
use the same version of Hamcrest classes by also delegating the
loading of org.hamcrest classes to FilteredClassLoader's parent.
parent 9a9c4c75
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -264,7 +264,7 @@ public class FilteredClassPathRunner extends BlockJUnit4ClassRunner { ...@@ -264,7 +264,7 @@ public class FilteredClassPathRunner extends BlockJUnit4ClassRunner {
@Override @Override
public Class<?> loadClass(String name) throws ClassNotFoundException { public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.startsWith("org.junit")) { if (name.startsWith("org.junit") || name.startsWith("org.hamcrest")) {
return this.junitLoader.loadClass(name); return this.junitLoader.loadClass(name);
} }
return super.loadClass(name); return super.loadClass(name);
......
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
package org.springframework.boot.testutil; package org.springframework.boot.testutil;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.isA;
/** /**
* Tests for {@link FilteredClassPathRunner} * Tests for {@link FilteredClassPathRunner}
...@@ -33,6 +36,9 @@ public class FilteredClassPathRunnerTests { ...@@ -33,6 +36,9 @@ public class FilteredClassPathRunnerTests {
private static final String EXCLUDED_RESOURCE = "META-INF/services/" private static final String EXCLUDED_RESOURCE = "META-INF/services/"
+ "javax.validation.spi.ValidationProvider"; + "javax.validation.spi.ValidationProvider";
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test @Test
public void entriesAreFilteredFromTestClassClassLoader() { public void entriesAreFilteredFromTestClassClassLoader() {
assertThat(getClass().getClassLoader().getResource(EXCLUDED_RESOURCE)).isNull(); assertThat(getClass().getClassLoader().getResource(EXCLUDED_RESOURCE)).isNull();
...@@ -44,4 +50,10 @@ public class FilteredClassPathRunnerTests { ...@@ -44,4 +50,10 @@ public class FilteredClassPathRunnerTests {
.getResource(EXCLUDED_RESOURCE)).isNull(); .getResource(EXCLUDED_RESOURCE)).isNull();
} }
@Test
public void testsThatUseHamcrestWorkCorrectly() {
this.thrown.expect(isA(IllegalStateException.class));
throw new IllegalStateException();
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment