pull/6191/merge
Phillip Webb 9 years ago
parent c136054e69
commit 7446235ff4

@ -30,6 +30,7 @@ import org.springframework.core.ResolvableType;
*
* @param <H> The health indicator type
* @param <S> T he bean source type
* @author Stephane Nicoll
* @since 1.4.0
*/
public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndicator, S> {
@ -61,8 +62,8 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
return indicatorClass.getConstructor(sourceClass).newInstance(source);
}
catch (Exception ex) {
throw new IllegalStateException("Unable to create indicator "
+ indicatorClass + " for source " + sourceClass, ex);
throw new IllegalStateException("Unable to create indicator " + indicatorClass
+ " for source " + sourceClass, ex);
}
}

@ -43,14 +43,14 @@ class ElasticsearchHealthIndicatorConfiguration {
@ConditionalOnBean(Client.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
static class SpringData extends
static class ElasticsearchSpringDataHealthIndicatorConfiguration extends
CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
private final Map<String, Client> clients;
private final ElasticsearchHealthIndicatorProperties properties;
SpringData(Map<String, Client> clients,
ElasticsearchSpringDataHealthIndicatorConfiguration(Map<String, Client> clients,
ElasticsearchHealthIndicatorProperties properties) {
this.clients = clients;
this.properties = properties;
@ -72,12 +72,12 @@ class ElasticsearchHealthIndicatorConfiguration {
@Configuration
@ConditionalOnBean(JestClient.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
static class Jest extends
static class ElasticsearchJestHealthIndicatorConfiguration extends
CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
private final Map<String, JestClient> clients;
Jest(Map<String, JestClient> clients) {
ElasticsearchJestHealthIndicatorConfiguration(Map<String, JestClient> clients) {
this.clients = clients;
}
@ -88,9 +88,11 @@ class ElasticsearchHealthIndicatorConfiguration {
}
@Override
protected ElasticsearchJestHealthIndicator createHealthIndicator(JestClient client) {
protected ElasticsearchJestHealthIndicator createHealthIndicator(
JestClient client) {
return new ElasticsearchJestHealthIndicator(client);
}
}
}

@ -98,8 +98,8 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
MongoDataAutoConfiguration.class, RabbitAutoConfiguration.class,
RedisAutoConfiguration.class, SolrAutoConfiguration.class })
@EnableConfigurationProperties({ HealthIndicatorProperties.class })
@Import({ ElasticsearchHealthIndicatorConfiguration.SpringData.class,
ElasticsearchHealthIndicatorConfiguration.Jest.class })
@Import({ ElasticsearchHealthIndicatorConfiguration.ElasticsearchSpringDataHealthIndicatorConfiguration.class,
ElasticsearchHealthIndicatorConfiguration.ElasticsearchJestHealthIndicatorConfiguration.class })
public class HealthIndicatorAutoConfiguration {
private final HealthIndicatorProperties properties;

@ -70,4 +70,5 @@ public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
builder.withDetail("initializingShards", response.getInitializingShards());
builder.withDetail("unassignedShards", response.getUnassignedShards());
}
}

@ -59,7 +59,6 @@ public class ElasticsearchJestHealthIndicatorTests {
public void elasticSearchIsDown() throws IOException {
given(this.jestClient.execute(any(Action.class))).willThrow(
new CouldNotConnectException("http://localhost:9200", new IOException()));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
}
@ -69,7 +68,6 @@ public class ElasticsearchJestHealthIndicatorTests {
public void elasticSearchIsOutOfService() throws IOException {
given(this.jestClient.execute(any(Action.class)))
.willReturn(createJestResult(4, 1));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
}
@ -77,7 +75,6 @@ public class ElasticsearchJestHealthIndicatorTests {
private static JestResult createJestResult(int shards, int failedShards) {
String json = String.format("{_shards: {\n" + "total: %s,\n" + "successful: %s,\n"
+ "failed: %s\n" + "}}", shards, shards - failedShards, failedShards);
SearchResult searchResult = new SearchResult(new Gson());
searchResult.setJsonString(json);
searchResult.setJsonObject(new JsonParser().parse(json).getAsJsonObject());

@ -48,7 +48,8 @@ public class JestAutoConfiguration {
private final ObjectProvider<Gson> gsonProvider;
public JestAutoConfiguration(JestProperties properties, ObjectProvider<Gson> gsonProvider) {
public JestAutoConfiguration(JestProperties properties,
ObjectProvider<Gson> gsonProvider) {
this.properties = properties;
this.gsonProvider = gsonProvider;
}
@ -62,8 +63,8 @@ public class JestAutoConfiguration {
}
protected HttpClientConfig createHttpClientConfig() {
HttpClientConfig.Builder builder = new HttpClientConfig
.Builder(this.properties.getUris());
HttpClientConfig.Builder builder = new HttpClientConfig.Builder(
this.properties.getUris());
if (StringUtils.hasText(this.properties.getUsername())) {
builder.defaultCredentials(this.properties.getUsername(),
this.properties.getPassword());
@ -73,8 +74,7 @@ public class JestAutoConfiguration {
builder.gson(gson);
}
return builder.connTimeout(this.properties.getConnectionTimeout())
.readTimeout(this.properties.getReadTimeout())
.build();
.readTimeout(this.properties.getReadTimeout()).build();
}
}

@ -132,7 +132,7 @@ class ArtemisConnectionFactoryFactory {
Constructor<T> constructor = factoryClass.getConstructor(boolean.class,
TransportConfiguration[].class);
T connectionFactory = constructor.newInstance(false,
new TransportConfiguration[] {transportConfiguration});
new TransportConfiguration[] { transportConfiguration });
String user = this.properties.getUser();
if (StringUtils.hasText(user)) {
connectionFactory.setUser(user);

@ -112,9 +112,10 @@ class HornetQConnectionFactoryFactory {
this.properties.getEmbedded().generateTransportParameters());
ServerLocator serviceLocator = HornetQClient
.createServerLocatorWithoutHA(transportConfiguration);
Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
ServerLocator.class);
return BeanUtils.instantiateClass(constructor, this.properties, serviceLocator);
Constructor<T> constructor = factoryClass
.getDeclaredConstructor(HornetQProperties.class, ServerLocator.class);
return BeanUtils.instantiateClass(constructor, this.properties,
serviceLocator);
}
catch (NoClassDefFoundError ex) {
throw new IllegalStateException("Unable to create InVM "
@ -130,8 +131,8 @@ class HornetQConnectionFactoryFactory {
params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort());
TransportConfiguration transportConfiguration = new TransportConfiguration(
NettyConnectorFactory.class.getName(), params);
Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
boolean.class, TransportConfiguration[].class);
Constructor<T> constructor = factoryClass.getDeclaredConstructor(
HornetQProperties.class, boolean.class, TransportConfiguration[].class);
return BeanUtils.instantiateClass(constructor, this.properties, false,
new TransportConfiguration[] { transportConfiguration });
}

@ -46,7 +46,7 @@ class HornetQXAConnectionFactoryConfiguration {
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory,
HornetQProperties properties, XAConnectionFactoryWrapper wrapper)
throws Exception {
throws Exception {
return wrapper.wrapConnectionFactory(
new HornetQConnectionFactoryFactory(beanFactory, properties)
.createConnectionFactory(

@ -47,6 +47,7 @@ class SpringBootHornetQConnectionFactory extends HornetQConnectionFactory {
this.properties = properties;
}
@Override
public Connection createConnection() throws JMSException {
String user = this.properties.getUser();
if (StringUtils.hasText(user)) {

@ -47,6 +47,7 @@ class SpringBootHornetQXAConnectionFactory extends HornetQXAConnectionFactory {
this.properties = properties;
}
@Override
public Connection createConnection() throws JMSException {
String user = this.properties.getUser();
if (StringUtils.hasText(user)) {

@ -209,7 +209,8 @@ public class MongoProperties {
}
String host = this.host == null ? "localhost" : this.host;
int port = determinePort(environment);
return new MongoClient(Collections.singletonList(new ServerAddress(host, port)),
return new MongoClient(
Collections.singletonList(new ServerAddress(host, port)),
credentials, options);
}
// The options and credentials are in the URI

@ -226,14 +226,13 @@ public class WebMvcAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
if (this.mvcProperties
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
else {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
@Bean

@ -42,7 +42,8 @@ public class WebMvcProperties {
private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
/**
* Locale to use. By default, this locale is overridden by the "Accept-Language" header.
* Locale to use. By default, this locale is overridden by the "Accept-Language"
* header.
*/
private Locale locale;
@ -261,8 +262,8 @@ public class WebMvcProperties {
FIXED,
/**
* Use the "Accept-Language" header or the configured locale if the header
* is not set.
* Use the "Accept-Language" header or the configured locale if the header is not
* set.
*/
ACCEPT_HEADER

@ -92,7 +92,8 @@ public class MongoAutoConfigurationTests {
MongoClient mongo = this.context.getBean(MongoClient.class);
MongoClientOptions options = mongo.getMongoClientOptions();
assertThat(options.isSslEnabled()).isTrue();
assertThat(options.getSocketFactory()).isSameAs(this.context.getBean("mySocketFactory"));
assertThat(options.getSocketFactory())
.isSameAs(this.context.getBean("mySocketFactory"));
}
@Configuration
@ -110,7 +111,8 @@ public class MongoAutoConfigurationTests {
@Bean
public MongoClientOptions mongoClientOptions() {
return MongoClientOptions.builder().sslEnabled(true).socketFactory(mySocketFactory()).build();
return MongoClientOptions.builder().sslEnabled(true)
.socketFactory(mySocketFactory()).build();
}
@Bean

@ -2637,20 +2637,21 @@ and http://hibernate.org/orm/documentation/[Hibernate] reference documentation.
[NOTE]
====
As of Hibernate 5.2, the `hibernate-entitymanager` module has been merged in
`hibernate-core`. If you need to downgrade, you'll have to add `hibernate-entitymanager`
yourself, something like:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
```
`hibernate-core`. If you need to downgrade, you'll need to directly add the
dependency yourself, for example:
[source,xml,indent=0]
----
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
----
As Hibernate does not bundle the `hibernate-entitymanager` and `hibernate-java8`
artifacts anymore, Spring Boot doesn't provide dependency management for them.
@ -3364,6 +3365,7 @@ configured:
To take full control over the registration, define a `JestClient` bean.
[[boot-features-connecting-to-elasticsearch]]
[[boot-features-connecting-to-elasticsearch-spring-data]]
==== Connecting to Elasticsearch using Spring Data

@ -19,7 +19,7 @@ package sample.jetty.jsp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.boot.web.support.SpringBootServletInitializer;
@SpringBootApplication
public class SampleJettyJspApplication extends SpringBootServletInitializer {

@ -172,12 +172,15 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
Element returns = this.processingEnv.getTypeUtils()
.asElement(element.getReturnType());
if (returns instanceof TypeElement) {
ItemMetadata group = ItemMetadata.newGroup(prefix, this.typeUtils.getType(returns),
ItemMetadata group = ItemMetadata.newGroup(prefix,
this.typeUtils.getType(returns),
this.typeUtils.getType(element.getEnclosingElement()),
element.toString());
if (this.metadataCollector.hasSimilarGroup(group)) {
this.processingEnv.getMessager().printMessage(Kind.ERROR,
"Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'", element);
"Duplicate `@ConfigurationProperties` definition for prefix '"
+ prefix + "'",
element);
}
else {
this.metadataCollector.add(group);

@ -19,8 +19,7 @@ package org.springframework.boot.configurationsample.specific;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Test that the same type can be registered several times if the prefix is
* different.
* Test that the same type can be registered several times if the prefix is different.
*
* @author Stephane Nicoll
*/

@ -31,13 +31,19 @@ import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.util.ClassUtils;
/**
* Jetty {@link AbstractLifeCycle} to initialize jasper.
* Jetty {@link AbstractLifeCycle} to initialize Jasper.
*
* @author Vladimir Tsanev
* @author Phillip Webb
*/
public class JasperInitializer extends AbstractLifeCycle {
class JasperInitializer extends AbstractLifeCycle {
private static final String[] INITIALIZER_CLASSES = {
"org.eclipse.jetty.apache.jsp.JettyJasperInitializer",
"org.apache.jasper.servlet.JasperInitializer" };
private final WebAppContext context;
private final ServletContainerInitializer initializer;
JasperInitializer(WebAppContext context) {
@ -45,24 +51,17 @@ public class JasperInitializer extends AbstractLifeCycle {
this.initializer = newInitializer();
}
private static ServletContainerInitializer newInitializer() {
try {
private ServletContainerInitializer newInitializer() {
for (String className : INITIALIZER_CLASSES) {
try {
return (ServletContainerInitializer) ClassUtils
.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer",
null)
.newInstance();
Class<?> initializerClass = ClassUtils.forName(className, null);
return (ServletContainerInitializer) initializerClass.newInstance();
}
catch (Exception ex) {
// try the original initializer
return (ServletContainerInitializer) ClassUtils
.forName("org.apache.jasper.servlet.JasperInitializer", null)
.newInstance();
// Ignore
}
}
catch (Exception ex) {
return null;
}
return null;
}
@Override
@ -71,22 +70,14 @@ public class JasperInitializer extends AbstractLifeCycle {
return;
}
try {
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if ("war".equals(protocol)) {
return new WarUrlStreamHandler();
}
return null;
}
});
URL.setURLStreamHandlerFactory(new WarUrlStreamHandlerFactory());
}
catch (Error ex) {
// Ignore
}
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
try {
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
try {
setExtendedListenerTypes(true);
this.initializer.onStartup(null, this.context.getServletContext());
@ -109,23 +100,36 @@ public class JasperInitializer extends AbstractLifeCycle {
}
}
/**
* {@link URLStreamHandlerFactory} to support {@literal war} protocol.
*/
private static class WarUrlStreamHandlerFactory implements URLStreamHandlerFactory {
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if ("war".equals(protocol)) {
return new WarUrlStreamHandler();
}
return null;
}
}
/**
* {@link URLStreamHandler} for {@literal war} protocol compatible with jasper's
* {@link URL urls} produced by
* {@link org.apache.tomcat.util.scan.JarFactory#getJarEntryURL(URL, String)}.
*/
static class WarUrlStreamHandler extends URLStreamHandler {
private static class WarUrlStreamHandler extends URLStreamHandler {
@Override
protected void parseURL(URL u, String spec, int start, int limit) {
String path = "jar:" + spec.substring("war:".length());
int separator = path.indexOf("*/");
if (separator >= 0) {
path = path.substring(0, separator) + "!/"
+ path.substring(separator + 2);
}
setURL(u, u.getProtocol(), "", -1, null, null, path, null, null);
}
@ -133,12 +137,13 @@ public class JasperInitializer extends AbstractLifeCycle {
protected URLConnection openConnection(URL u) throws IOException {
return new WarURLConnection(u);
}
}
/**
* {@link URLConnection} to support {@literal war} protocol.
*/
static class WarURLConnection extends URLConnection {
private static class WarURLConnection extends URLConnection {
private final URLConnection connection;
@ -160,6 +165,7 @@ public class JasperInitializer extends AbstractLifeCycle {
connect();
return this.connection.getInputStream();
}
}
}

@ -0,0 +1,113 @@
/*
* 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.
*/
package org.springframework.boot.context.embedded.tomcat;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.KeyStore;
import org.springframework.boot.context.embedded.SslStoreProvider;
/**
* A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for
* accessing an {@link SslStoreProvider}'s key store and trust store from a URL.
*
* @author Andy Wilkinson
*/
class SslStoreProviderUrlStreamHandlerFactory implements URLStreamHandlerFactory {
private static final String PROTOCOL = "springbootssl";
private static final String KEY_STORE_PATH = "keyStore";
static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH;
private static final String TRUST_STORE_PATH = "trustStore";
static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH;
private final SslStoreProvider sslStoreProvider;
SslStoreProviderUrlStreamHandlerFactory(SslStoreProvider sslStoreProvider) {
this.sslStoreProvider = sslStoreProvider;
}
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if (PROTOCOL.equals(protocol)) {
return new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL url) throws IOException {
try {
if (KEY_STORE_PATH.equals(url.getPath())) {
return new KeyStoreUrlConnection(url,
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
.getKeyStore());
}
if (TRUST_STORE_PATH.equals(url.getPath())) {
return new KeyStoreUrlConnection(url,
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
.getTrustStore());
}
}
catch (Exception ex) {
throw new IOException(ex);
}
throw new IOException("Invalid path: " + url.getPath());
}
};
}
return null;
}
private static final class KeyStoreUrlConnection extends URLConnection {
private final KeyStore keyStore;
private KeyStoreUrlConnection(URL url, KeyStore keyStore) {
super(url);
this.keyStore = keyStore;
}
@Override
public void connect() throws IOException {
}
@Override
public InputStream getInputStream() throws IOException {
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
this.keyStore.store(stream, new char[0]);
return new ByteArrayInputStream(stream.toByteArray());
}
catch (Exception ex) {
throw new IOException(ex);
}
}
}
}

@ -16,19 +16,11 @@
package org.springframework.boot.context.embedded.tomcat;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -63,7 +55,6 @@ import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.Compression;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
@ -79,7 +70,6 @@ import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
@ -702,158 +692,6 @@ public class TomcatEmbeddedServletContainerFactory
return this.uriEncoding;
}
/**
* A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for
* accessing an {@link SslStoreProvider}'s key store and trust store from a URL.
*/
private static final class SslStoreProviderUrlStreamHandlerFactory
implements URLStreamHandlerFactory {
private static final String PROTOCOL = "springbootssl";
private static final String KEY_STORE_PATH = "keyStore";
private static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH;
private static final String TRUST_STORE_PATH = "trustStore";
private static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH;
private final SslStoreProvider sslStoreProvider;
private SslStoreProviderUrlStreamHandlerFactory(
SslStoreProvider sslStoreProvider) {
this.sslStoreProvider = sslStoreProvider;
}
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if (PROTOCOL.equals(protocol)) {
return new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL url) throws IOException {
try {
if (KEY_STORE_PATH.equals(url.getPath())) {
return new KeyStoreUrlConnection(url,
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
.getKeyStore());
}
if (TRUST_STORE_PATH.equals(url.getPath())) {
return new KeyStoreUrlConnection(url,
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
.getTrustStore());
}
}
catch (Exception ex) {
throw new IOException(ex);
}
throw new IOException("Invalid path: " + url.getPath());
}
};
}
return null;
}
private static final class KeyStoreUrlConnection extends URLConnection {
private final KeyStore keyStore;
private KeyStoreUrlConnection(URL url, KeyStore keyStore) {
super(url);
this.keyStore = keyStore;
}
@Override
public void connect() throws IOException {
}
@Override
public InputStream getInputStream() throws IOException {
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
this.keyStore.store(stream, new char[0]);
return new ByteArrayInputStream(stream.toByteArray());
}
catch (Exception ex) {
throw new IOException(ex);
}
}
}
}
private static class TomcatErrorPage {
private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage";
private static final String LEGACY_ERROR_PAGE_CLASS = "org.apache.catalina.deploy.ErrorPage";
private final String location;
private final String exceptionType;
private final int errorCode;
private final Object nativePage;
TomcatErrorPage(ErrorPage errorPage) {
this.location = errorPage.getPath();
this.exceptionType = errorPage.getExceptionName();
this.errorCode = errorPage.getStatusCode();
this.nativePage = createNativePage(errorPage);
}
private Object createNativePage(ErrorPage errorPage) {
Object nativePage = null;
try {
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
nativePage = BeanUtils
.instantiate(ClassUtils.forName(ERROR_PAGE_CLASS, null));
}
else if (ClassUtils.isPresent(LEGACY_ERROR_PAGE_CLASS, null)) {
nativePage = BeanUtils.instantiate(
ClassUtils.forName(LEGACY_ERROR_PAGE_CLASS, null));
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
catch (LinkageError ex) {
// Swallow and continue
}
return nativePage;
}
public void addToContext(Context context) {
Assert.state(this.nativePage != null,
"Neither Tomcat 7 nor 8 detected so no native error page exists");
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
org.apache.tomcat.util.descriptor.web.ErrorPage errorPage = (org.apache.tomcat.util.descriptor.web.ErrorPage) this.nativePage;
errorPage.setLocation(this.location);
errorPage.setErrorCode(this.errorCode);
errorPage.setExceptionType(this.exceptionType);
context.addErrorPage(errorPage);
}
else {
callMethod(this.nativePage, "setLocation", this.location, String.class);
callMethod(this.nativePage, "setErrorCode", this.errorCode, int.class);
callMethod(this.nativePage, "setExceptionType", this.exceptionType,
String.class);
callMethod(context, "addErrorPage", this.nativePage,
this.nativePage.getClass());
}
}
private void callMethod(Object target, String name, Object value, Class<?> type) {
Method method = ReflectionUtils.findMethod(target.getClass(), name, type);
ReflectionUtils.invokeMethod(method, target, value);
}
}
/**
* {@link LifecycleListener} that stores an empty merged web.xml. This is critical for
* Jasper to prevent warnings about missing web.xml files and to enable EL.

@ -0,0 +1,102 @@
/*
* 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.
*/
package org.springframework.boot.context.embedded.tomcat;
import java.lang.reflect.Method;
import org.apache.catalina.Context;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* Tomcat specific management for an {@link ErrorPage}.
*
* @author Dave Syer
* @author Phillip Webb
*/
class TomcatErrorPage {
private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage";
private static final String LEGACY_ERROR_PAGE_CLASS = "org.apache.catalina.deploy.ErrorPage";
private final String location;
private final String exceptionType;
private final int errorCode;
private final Object nativePage;
TomcatErrorPage(ErrorPage errorPage) {
this.location = errorPage.getPath();
this.exceptionType = errorPage.getExceptionName();
this.errorCode = errorPage.getStatusCode();
this.nativePage = createNativePage(errorPage);
}
private Object createNativePage(ErrorPage errorPage) {
Object nativePage = null;
try {
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
nativePage = BeanUtils
.instantiate(ClassUtils.forName(ERROR_PAGE_CLASS, null));
}
else if (ClassUtils.isPresent(LEGACY_ERROR_PAGE_CLASS, null)) {
nativePage = BeanUtils
.instantiate(ClassUtils.forName(LEGACY_ERROR_PAGE_CLASS, null));
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
catch (LinkageError ex) {
// Swallow and continue
}
return nativePage;
}
public void addToContext(Context context) {
Assert.state(this.nativePage != null,
"Neither Tomcat 7 nor 8 detected so no native error page exists");
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
org.apache.tomcat.util.descriptor.web.ErrorPage errorPage = (org.apache.tomcat.util.descriptor.web.ErrorPage) this.nativePage;
errorPage.setLocation(this.location);
errorPage.setErrorCode(this.errorCode);
errorPage.setExceptionType(this.exceptionType);
context.addErrorPage(errorPage);
}
else {
callMethod(this.nativePage, "setLocation", this.location, String.class);
callMethod(this.nativePage, "setErrorCode", this.errorCode, int.class);
callMethod(this.nativePage, "setExceptionType", this.exceptionType,
String.class);
callMethod(context, "addErrorPage", this.nativePage,
this.nativePage.getClass());
}
}
private void callMethod(Object target, String name, Object value, Class<?> type) {
Method method = ReflectionUtils.findMethod(target.getClass(), name, type);
ReflectionUtils.invokeMethod(method, target, value);
}
}

@ -33,10 +33,9 @@ import com.google.gson.reflect.TypeToken;
*/
public class GsonJsonParser implements JsonParser {
private static final TypeToken<List<Object>> LIST_TYPE = new TypeToken<List<Object>>() {
};
private static final TypeToken<Map<String, Object>> MAP_TYPE = new TypeToken<Map<String, Object>>() {
};
private static final TypeToken<?> MAP_TYPE = new MapTypeToken();
private static final TypeToken<?> LIST_TYPE = new ListTypeToken();
private Gson gson = new GsonBuilder().create();
@ -62,4 +61,12 @@ public class GsonJsonParser implements JsonParser {
throw new IllegalArgumentException("Cannot parse JSON");
}
private static final class MapTypeToken extends TypeToken<Map<String, Object>> {
}
private static final class ListTypeToken extends TypeToken<List<Object>> {
}
}

@ -30,10 +30,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*/
public class JacksonJsonParser implements JsonParser {
private static final TypeReference<List<Object>> LIST_TYPE = new TypeReference<List<Object>>() {
};
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<Map<String, Object>>() {
};
private static final TypeReference<?> MAP_TYPE = new MapTypeReference();
private static final TypeReference<?> LIST_TYPE = new ListTypeReference();
private final ObjectMapper objectMapper = new ObjectMapper();
@ -57,4 +56,12 @@ public class JacksonJsonParser implements JsonParser {
}
}
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
};
private static class ListTypeReference extends TypeReference<List<Object>> {
};
}

@ -79,12 +79,10 @@ public class TestEntityScanTests {
@Test
public void valueAndBasePackagesThrows() throws Exception {
this.thrown.expect(AnnotationConfigurationException.class);
this.thrown.expectMessage(allOf(
containsString("'value'"),
containsString("'basePackages'"),
containsString("com.mycorp.entity"),
this.thrown.expectMessage(allOf(containsString("'value'"),
containsString("'basePackages'"), containsString("com.mycorp.entity"),
containsString("com.mycorp")));
new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
}
@Test

@ -78,12 +78,10 @@ public class ServletComponentScanRegistrarTests {
@Test
public void packagesConfiguredWithBothValueAndBasePackages() {
this.thrown.expect(AnnotationConfigurationException.class);
this.thrown.expectMessage(allOf(
containsString("'value'"),
containsString("'basePackages'"),
containsString("com.example.foo"),
this.thrown.expectMessage(allOf(containsString("'value'"),
containsString("'basePackages'"), containsString("com.example.foo"),
containsString("com.example.bar")));
new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
}
@Test

Loading…
Cancel
Save