Commit 20d7dd57 authored by Phillip Webb's avatar Phillip Webb

Merge branch '1.5.x'

parents 9ec38dc8 16571202
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
<module>spring-boot-dependencies</module> <module>spring-boot-dependencies</module>
<module>spring-boot-parent</module> <module>spring-boot-parent</module>
<module>spring-boot-tools</module> <module>spring-boot-tools</module>
<module>spring-boot-junit-runners</module>
<module>spring-boot</module> <module>spring-boot</module>
<module>spring-boot-test</module> <module>spring-boot-test</module>
<module>spring-boot-autoconfigure</module> <module>spring-boot-autoconfigure</module>
......
...@@ -277,6 +277,11 @@ ...@@ -277,6 +277,11 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId> <artifactId>spring-boot-test</artifactId>
......
...@@ -23,6 +23,7 @@ import java.util.List; ...@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.mvc.AbstractEndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.mvc.AbstractEndpointHandlerMapping;
...@@ -34,6 +35,7 @@ import org.springframework.web.cors.CorsConfiguration; ...@@ -34,6 +35,7 @@ import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/** /**
* {@link HandlerMapping} to map {@link Endpoint}s to Cloud Foundry specific URLs. * {@link HandlerMapping} to map {@link Endpoint}s to Cloud Foundry specific URLs.
...@@ -45,10 +47,13 @@ class CloudFoundryEndpointHandlerMapping ...@@ -45,10 +47,13 @@ class CloudFoundryEndpointHandlerMapping
private final HandlerInterceptor securityInterceptor; private final HandlerInterceptor securityInterceptor;
private final CorsConfiguration corsConfiguration;
CloudFoundryEndpointHandlerMapping(Set<? extends NamedMvcEndpoint> endpoints, CloudFoundryEndpointHandlerMapping(Set<? extends NamedMvcEndpoint> endpoints,
CorsConfiguration corsConfiguration, HandlerInterceptor securityInterceptor) { CorsConfiguration corsConfiguration, HandlerInterceptor securityInterceptor) {
super(endpoints, corsConfiguration); super(endpoints, corsConfiguration);
this.securityInterceptor = securityInterceptor; this.securityInterceptor = securityInterceptor;
this.corsConfiguration = corsConfiguration;
} }
@Override @Override
...@@ -97,6 +102,7 @@ class CloudFoundryEndpointHandlerMapping ...@@ -97,6 +102,7 @@ class CloudFoundryEndpointHandlerMapping
private HandlerInterceptor[] addSecurityInterceptor(HandlerInterceptor[] existing) { private HandlerInterceptor[] addSecurityInterceptor(HandlerInterceptor[] existing) {
List<HandlerInterceptor> interceptors = new ArrayList<HandlerInterceptor>(); List<HandlerInterceptor> interceptors = new ArrayList<HandlerInterceptor>();
interceptors.add(new CorsInterceptor(this.corsConfiguration));
interceptors.add(this.securityInterceptor); interceptors.add(this.securityInterceptor);
if (existing != null) { if (existing != null) {
interceptors.addAll(Arrays.asList(existing)); interceptors.addAll(Arrays.asList(existing));
...@@ -104,4 +110,23 @@ class CloudFoundryEndpointHandlerMapping ...@@ -104,4 +110,23 @@ class CloudFoundryEndpointHandlerMapping
return interceptors.toArray(new HandlerInterceptor[interceptors.size()]); return interceptors.toArray(new HandlerInterceptor[interceptors.size()]);
} }
/**
* {@link HandlerInterceptor} that processes the response for CORS.
*/
class CorsInterceptor extends HandlerInterceptorAdapter {
private final CorsConfiguration config;
CorsInterceptor(CorsConfiguration config) {
this.config = config;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
return getCorsProcessor().processRequest(this.config, request, response);
}
}
} }
...@@ -20,9 +20,9 @@ import org.junit.After; ...@@ -20,9 +20,9 @@ import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.testutil.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
......
...@@ -33,11 +33,16 @@ import org.springframework.boot.actuate.health.HealthIndicator; ...@@ -33,11 +33,16 @@ import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator; import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.context.support.StaticApplicationContext; import org.springframework.context.support.StaticApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsProcessor;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/** /**
* Tests for {@link CloudFoundryEndpointHandlerMapping}. * Tests for {@link CloudFoundryEndpointHandlerMapping}.
...@@ -47,6 +52,24 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -47,6 +52,24 @@ import static org.assertj.core.api.Assertions.assertThat;
public class CloudFoundryEndpointHandlerMappingTests public class CloudFoundryEndpointHandlerMappingTests
extends AbstractEndpointHandlerMappingTests { extends AbstractEndpointHandlerMappingTests {
@Test
public void corsInterceptorShouldBeFirstAndCallCorsProcessor() throws Exception {
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
CorsConfiguration corsConfiguration = new CorsConfiguration();
CloudFoundryEndpointHandlerMapping handlerMapping = new CloudFoundryEndpointHandlerMapping(
Collections.singleton(endpoint), corsConfiguration, null);
CorsProcessor corsProcessor = mock(CorsProcessor.class);
handlerMapping.setCorsProcessor(corsProcessor);
MockHttpServletRequest request = new MockHttpServletRequest();
HandlerExecutionChain handlerExecutionChain = handlerMapping
.getHandlerExecutionChain(endpoint, request);
HandlerInterceptor[] interceptors = handlerExecutionChain.getInterceptors();
CloudFoundryEndpointHandlerMapping.CorsInterceptor corsInterceptor = (CloudFoundryEndpointHandlerMapping.CorsInterceptor) interceptors[0];
MockHttpServletResponse response = new MockHttpServletResponse();
corsInterceptor.preHandle(request, response, new Object());
verify(corsProcessor).processRequest(corsConfiguration, request, response);
}
@Test @Test
public void getHandlerExecutionChainShouldHaveSecurityInterceptor() throws Exception { public void getHandlerExecutionChainShouldHaveSecurityInterceptor() throws Exception {
CloudFoundrySecurityInterceptor securityInterceptor = Mockito CloudFoundrySecurityInterceptor securityInterceptor = Mockito
...@@ -57,7 +80,7 @@ public class CloudFoundryEndpointHandlerMappingTests ...@@ -57,7 +80,7 @@ public class CloudFoundryEndpointHandlerMappingTests
HandlerExecutionChain handlerExecutionChain = handlerMapping HandlerExecutionChain handlerExecutionChain = handlerMapping
.getHandlerExecutionChain(endpoint, new MockHttpServletRequest()); .getHandlerExecutionChain(endpoint, new MockHttpServletRequest());
HandlerInterceptor[] interceptors = handlerExecutionChain.getInterceptors(); HandlerInterceptor[] interceptors = handlerExecutionChain.getInterceptors();
assertThat(interceptors).contains(securityInterceptor); assertThat(interceptors[1]).isEqualTo(securityInterceptor);
} }
@Test @Test
......
...@@ -30,8 +30,8 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati ...@@ -30,8 +30,8 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.testutil.ClassPathExclusions; import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockServletContext;
......
...@@ -619,6 +619,11 @@ ...@@ -619,6 +619,11 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId> <artifactId>spring-boot-test</artifactId>
......
...@@ -1035,8 +1035,8 @@ public class ServerProperties ...@@ -1035,8 +1035,8 @@ public class ServerProperties
private boolean renameOnRotate; private boolean renameOnRotate;
/** /**
* Set request attributes for IP address, Hostname, protocol and port used * Set request attributes for IP address, Hostname, protocol and port used for
* for the request. * the request.
*/ */
private boolean requestAttributesEnabled; private boolean requestAttributesEnabled;
......
...@@ -21,8 +21,8 @@ import org.junit.Test; ...@@ -21,8 +21,8 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.condition.OnBeanCondition.BeanTypeDeductionException; import org.springframework.boot.autoconfigure.condition.OnBeanCondition.BeanTypeDeductionException;
import org.springframework.boot.testutil.ClassPathExclusions; import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
......
...@@ -22,8 +22,8 @@ import org.junit.runner.RunWith; ...@@ -22,8 +22,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.testutil.ClassPathExclusions; import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
......
...@@ -199,6 +199,11 @@ ...@@ -199,6 +199,11 @@
<type>test-jar</type> <type>test-jar</type>
<version>2.0.0.BUILD-SNAPSHOT</version> <version>2.0.0.BUILD-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<version>1.5.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId> <artifactId>spring-boot-test</artifactId>
......
...@@ -92,6 +92,11 @@ ...@@ -92,6 +92,11 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId> <artifactId>spring-boot-test</artifactId>
......
...@@ -21,12 +21,8 @@ import java.io.InputStream; ...@@ -21,12 +21,8 @@ import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
...@@ -48,9 +44,8 @@ import org.springframework.util.AntPathMatcher; ...@@ -48,9 +44,8 @@ import org.springframework.util.AntPathMatcher;
*/ */
final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternResolver { final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternResolver {
private static final Set<String> LOCATION_PATTERN_PREFIXES = Collections private static final String[] LOCATION_PATTERN_PREFIXES = { CLASSPATH_ALL_URL_PREFIX,
.unmodifiableSet(new HashSet<String>( CLASSPATH_URL_PREFIX };
Arrays.asList(CLASSPATH_ALL_URL_PREFIX, CLASSPATH_URL_PREFIX)));
private final ResourcePatternResolver delegate = new PathMatchingResourcePatternResolver(); private final ResourcePatternResolver delegate = new PathMatchingResourcePatternResolver();
...@@ -62,26 +57,26 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe ...@@ -62,26 +57,26 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
this.classLoaderFiles = classLoaderFiles; this.classLoaderFiles = classLoaderFiles;
} }
@Override
public ClassLoader getClassLoader() {
return this.delegate.getClassLoader();
}
@Override @Override
public Resource getResource(String location) { public Resource getResource(String location) {
Resource candidate = this.delegate.getResource(location); Resource candidate = this.delegate.getResource(location);
if (isExcludedResource(candidate)) { if (isDeleted(candidate)) {
return new DeletedClassLoaderFileResource(location); return new DeletedClassLoaderFileResource(location);
} }
return candidate; return candidate;
} }
@Override
public ClassLoader getClassLoader() {
return this.delegate.getClassLoader();
}
@Override @Override
public Resource[] getResources(String locationPattern) throws IOException { public Resource[] getResources(String locationPattern) throws IOException {
List<Resource> resources = new ArrayList<Resource>(); List<Resource> resources = new ArrayList<Resource>();
Resource[] candidates = this.delegate.getResources(locationPattern); Resource[] candidates = this.delegate.getResources(locationPattern);
for (Resource candidate : candidates) { for (Resource candidate : candidates) {
if (!isExcludedResource(candidate)) { if (!isDeleted(candidate)) {
resources.add(candidate); resources.add(candidate);
} }
} }
...@@ -89,38 +84,43 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe ...@@ -89,38 +84,43 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
return resources.toArray(new Resource[resources.size()]); return resources.toArray(new Resource[resources.size()]);
} }
private String trimLocationPattern(String locationPattern) {
for (String prefix : LOCATION_PATTERN_PREFIXES) {
if (locationPattern.startsWith(prefix)) {
return locationPattern.substring(prefix.length());
}
}
return locationPattern;
}
private List<Resource> getAdditionalResources(String locationPattern) private List<Resource> getAdditionalResources(String locationPattern)
throws MalformedURLException { throws MalformedURLException {
List<Resource> additionalResources = new ArrayList<Resource>(); List<Resource> additionalResources = new ArrayList<Resource>();
String trimmedLocationPattern = trimLocationPattern(locationPattern); String trimmedLocationPattern = trimLocationPattern(locationPattern);
for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) { for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) {
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) { for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
if (entry.getValue().getKind() == Kind.ADDED && this.antPathMatcher String name = entry.getKey();
.match(trimmedLocationPattern, entry.getKey())) { ClassLoaderFile file = entry.getValue();
additionalResources.add(new UrlResource(new URL("reloaded", null, -1, if (file.getKind() == Kind.ADDED
"/" + entry.getKey(), && this.antPathMatcher.match(trimmedLocationPattern, name)) {
new ClassLoaderFileURLStreamHandler(entry.getValue())))); URL url = new URL("reloaded", null, -1, "/" + name,
new ClassLoaderFileURLStreamHandler(file));
UrlResource resource = new UrlResource(url);
additionalResources.add(resource);
} }
} }
} }
return additionalResources; return additionalResources;
} }
private boolean isExcludedResource(Resource resource) { private String trimLocationPattern(String pattern) {
for (String prefix : LOCATION_PATTERN_PREFIXES) {
if (pattern.startsWith(prefix)) {
return pattern.substring(prefix.length());
}
}
return pattern;
}
private boolean isDeleted(Resource resource) {
for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) { for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) {
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) { for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
try { try {
if (entry.getValue().getKind() == Kind.DELETED && resource.exists() String name = entry.getKey();
&& resource.getURI().toString().endsWith(entry.getKey())) { ClassLoaderFile file = entry.getValue();
if (file.getKind() == Kind.DELETED && resource.exists()
&& resource.getURI().toString().endsWith(name)) {
return true; return true;
} }
} }
...@@ -136,8 +136,6 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe ...@@ -136,8 +136,6 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
/** /**
* A {@link Resource} that represents a {@link ClassLoaderFile} that has been * A {@link Resource} that represents a {@link ClassLoaderFile} that has been
* {@link Kind#DELETED deleted}. * {@link Kind#DELETED deleted}.
*
* @author Andy Wilkinson
*/ */
private final class DeletedClassLoaderFileResource extends AbstractResource { private final class DeletedClassLoaderFileResource extends AbstractResource {
...@@ -161,5 +159,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe ...@@ -161,5 +159,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
throw new IOException(this.name + " has been deleted"); throw new IOException(this.name + " has been deleted");
} }
} }
} }
...@@ -421,8 +421,7 @@ public class Restarter { ...@@ -421,8 +421,7 @@ public class Restarter {
return; return;
} }
if (applicationContext instanceof GenericApplicationContext) { if (applicationContext instanceof GenericApplicationContext) {
((GenericApplicationContext) applicationContext).setResourceLoader( prepare((GenericApplicationContext) applicationContext);
new ClassLoaderFilesResourcePatternResolver(this.classLoaderFiles));
} }
this.rootContexts.add(applicationContext); this.rootContexts.add(applicationContext);
} }
...@@ -433,6 +432,11 @@ public class Restarter { ...@@ -433,6 +432,11 @@ public class Restarter {
} }
} }
private void prepare(GenericApplicationContext applicationContext) {
applicationContext.setResourceLoader(
new ClassLoaderFilesResourcePatternResolver(this.classLoaderFiles));
}
private LeakSafeThread getLeakSafeThread() { private LeakSafeThread getLeakSafeThread() {
try { try {
return this.leakSafeThreads.takeFirst(); return this.leakSafeThreads.takeFirst();
......
...@@ -27,6 +27,7 @@ import java.net.URLStreamHandler; ...@@ -27,6 +27,7 @@ import java.net.URLStreamHandler;
* {@link URLStreamHandler} for the contents of a {@link ClassLoaderFile}. * {@link URLStreamHandler} for the contents of a {@link ClassLoaderFile}.
* *
* @author Phillip Webb * @author Phillip Webb
* @since 1.5.0
*/ */
public class ClassLoaderFileURLStreamHandler extends URLStreamHandler { public class ClassLoaderFileURLStreamHandler extends URLStreamHandler {
......
...@@ -25,8 +25,8 @@ import org.junit.Test; ...@@ -25,8 +25,8 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.testutil.ClassPathExclusions; import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
......
...@@ -725,6 +725,11 @@ ...@@ -725,6 +725,11 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
......
...@@ -20,9 +20,9 @@ import org.junit.Rule; ...@@ -20,9 +20,9 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.boot.test.rule.OutputCapture; import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.boot.testutil.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
<module>../spring-boot-dependencies</module> <module>../spring-boot-dependencies</module>
<module>../spring-boot-parent</module> <module>../spring-boot-parent</module>
<module>../spring-boot-tools</module> <module>../spring-boot-tools</module>
<module>../spring-boot-junit-runners</module>
<module>../spring-boot</module> <module>../spring-boot</module>
<module>../spring-boot-test</module> <module>../spring-boot-test</module>
<module>../spring-boot-autoconfigure</module> <module>../spring-boot-autoconfigure</module>
......
...@@ -146,8 +146,8 @@ public class DevToolsIntegrationTests { ...@@ -146,8 +146,8 @@ public class DevToolsIntegrationTests {
} }
Thread.sleep(100); Thread.sleep(100);
} }
int port = Integer FileReader portReader = new FileReader(this.serverPortFile);
.valueOf(FileCopyUtils.copyToString(new FileReader(this.serverPortFile))); int port = Integer.valueOf(FileCopyUtils.copyToString(portReader));
this.serverPortFile.delete(); this.serverPortFile.delete();
return port; return port;
} }
...@@ -187,5 +187,7 @@ public class DevToolsIntegrationTests { ...@@ -187,5 +187,7 @@ public class DevToolsIntegrationTests {
} }
builder.make().saveIn(this.classesDirectory); builder.make().saveIn(this.classesDirectory);
} }
} }
} }
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>1.5.0.BUILD-SNAPSHOT</version>
<relativePath>../spring-boot-parent</relativePath>
</parent>
<artifactId>spring-boot-junit-runners</artifactId>
<name>Spring Boot JUnit Runners</name>
<description>Spring Boot JUnit Runners</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/..</main.basedir>
</properties>
<dependencies>
<!-- Provided -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
<!-- Compile -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<exclusions>
<exclusion>
<artifactId>org.eclipse.sisu.plexus</artifactId>
<groupId>org.eclipse.sisu</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-settings-builder</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-impl</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-spi</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-file</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-http</artifactId>
<exclusions>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-util</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>io.projectreactor.spring</groupId>
<artifactId>reactor-spring-context</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.testutil; package org.springframework.boot.junit.runner.classpath;
import java.io.File; import java.io.File;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.testutil; package org.springframework.boot.junit.runner.classpath;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.testutil; package org.springframework.boot.junit.runner.classpath;
import java.io.File; import java.io.File;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
......
/*
* Copyright 2012-2016 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.
*/
/**
* Custom JUnit runner to change the classpath.
*/
package org.springframework.boot.junit.runner.classpath;
/*
* Copyright 2012-2016 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.
*/
/**
* Custom JUnit runners used in Spring Boot's own tests.
*/
package org.springframework.boot.junit.runner;
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.testutil; package org.springframework.boot.junit.runner.classpath;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.testutil; package org.springframework.boot.junit.runner.classpath;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- This POM is just to trigger the Ant/Ivy sample from Maven and to test --> <!-- This POM is just to trigger the Ant/Ivy sample from Maven and to test -->
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
...@@ -60,8 +59,8 @@ ...@@ -60,8 +59,8 @@
<phase>package</phase> <phase>package</phase>
<configuration> <configuration>
<target> <target>
<property name="build.compiler" value="extJavac" /> <property name="build.compiler" value="extJavac"/>
<ant dir="${basedir}" /> <ant dir="${basedir}"/>
</target> </target>
</configuration> </configuration>
<goals> <goals>
......
...@@ -118,6 +118,11 @@ ...@@ -118,6 +118,11 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-runtime</artifactId> <artifactId>kotlin-runtime</artifactId>
......
...@@ -21,8 +21,8 @@ import org.junit.runner.JUnitCore; ...@@ -21,8 +21,8 @@ import org.junit.runner.JUnitCore;
import org.junit.runner.Result; import org.junit.runner.Result;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.testutil.ClassPathOverrides; import org.springframework.boot.junit.runner.classpath.ClassPathOverrides;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
......
...@@ -21,8 +21,8 @@ import org.junit.runner.JUnitCore; ...@@ -21,8 +21,8 @@ import org.junit.runner.JUnitCore;
import org.junit.runner.Result; import org.junit.runner.Result;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.testutil.ClassPathOverrides; import org.springframework.boot.junit.runner.classpath.ClassPathOverrides;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
......
...@@ -246,6 +246,11 @@ ...@@ -246,6 +246,11 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-junit-runners</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>com.google.appengine</groupId> <groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId> <artifactId>appengine-api-1.0-sdk</artifactId>
...@@ -290,64 +295,6 @@ ...@@ -290,64 +295,6 @@
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId> <artifactId>httpasyncclient</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<exclusions>
<exclusion>
<artifactId>org.eclipse.sisu.plexus</artifactId>
<groupId>org.eclipse.sisu</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-settings-builder</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-impl</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-spi</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-file</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-http</artifactId>
<exclusions>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-util</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.firebirdsql.jdbc</groupId> <groupId>org.firebirdsql.jdbc</groupId>
......
...@@ -22,8 +22,8 @@ import org.junit.runner.RunWith; ...@@ -22,8 +22,8 @@ import org.junit.runner.RunWith;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.testutil.ClassPathExclusions; import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testutil.ModifiedClassPathRunner; import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
......
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