Change Jersey init to avoid classpath scanning issues
Scan classpath for Jersey resources with Spring and initialize the Jersey filter with a jaxrs Application instead. (Fixes gh-399, fixes gh-400)
This commit is contained in:
committed by
Dave Syer
parent
2ba5c4b9ec
commit
58284a4508
@@ -225,46 +225,6 @@ normal Eureka functionality under `/eureka/*`.
|
||||
|
||||
Eureka background reading: see https://github.com/cfregly/fluxcapacitor/wiki/NetflixOSS-FAQ#eureka-service-discovery-load-balancer[flux capacitor] and https://groups.google.com/forum/?fromgroups#!topic/eureka_netflix/g3p2r7gHnN0[google group discussion].
|
||||
|
||||
[TIP]
|
||||
====
|
||||
You can run the Eureka server as an executable JAR (or WAR) using the
|
||||
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins[Spring
|
||||
Boot build tools], but to avoid problems with classpath scanning in
|
||||
Jersey 1.x you have to tell the build plugins to unpack the jars that
|
||||
contain JAX-RS resources, e.g. (for Maven)
|
||||
|
||||
.pom.xml
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<requiresUnpack>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
</dependency>
|
||||
</requiresUnpack>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
|
||||
or with Gradle
|
||||
|
||||
.build.gradle
|
||||
[source,java,indent=0]
|
||||
----
|
||||
apply plugin: 'spring-boot'
|
||||
springBoot {
|
||||
requiresUnpack = ['com.netflix.eureka:eureka-core','com.netflix.eureka:eureka-client']
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[TIP]
|
||||
====
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
|
||||
@@ -17,21 +17,34 @@
|
||||
package org.springframework.cloud.netflix.eureka.server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.embedded.FilterRegistrationBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaServerConfigBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sun.jersey.api.core.DefaultResourceConfig;
|
||||
import com.sun.jersey.spi.container.servlet.ServletContainer;
|
||||
|
||||
/**
|
||||
@@ -42,27 +55,76 @@ import com.sun.jersey.spi.container.servlet.ServletContainer;
|
||||
@EnableDiscoveryClient
|
||||
@EnableConfigurationProperties(EurekaDashboardProperties.class)
|
||||
public class EurekaServerConfiguration extends WebMvcConfigurerAdapter {
|
||||
|
||||
/**
|
||||
* List of packages containing Jersey resources required by the Eureka server
|
||||
*/
|
||||
private static String[] EUREKA_PACKAGES = new String[] {
|
||||
"com.netflix.discovery",
|
||||
"com.netflix.eureka"};
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "eureka.dashboard", name = "enabled", matchIfMissing = true)
|
||||
public EurekaController eurekaController() {
|
||||
return new EurekaController();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Jersey filter
|
||||
*
|
||||
* @param eurekaJerseyApp the jersey application
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean jersey() {
|
||||
public FilterRegistrationBean jerseyFilterRegistration(javax.ws.rs.core.Application eurekaJerseyApp) {
|
||||
FilterRegistrationBean bean = new FilterRegistrationBean();
|
||||
bean.setFilter(new ServletContainer());
|
||||
bean.setFilter(new ServletContainer(eurekaJerseyApp));
|
||||
bean.setOrder(Ordered.LOWEST_PRECEDENCE);
|
||||
bean.addInitParameter("com.sun.jersey.config.property.WebPageContentRegex",
|
||||
EurekaServerConfigBean.DEFAULT_PREFIX + "/(fonts|images|css|js)/.*");
|
||||
bean.addInitParameter("com.sun.jersey.config.property.packages",
|
||||
"com.netflix.discovery;com.netflix.eureka");
|
||||
bean.setUrlPatterns(Collections
|
||||
.singletonList(EurekaServerConfigBean.DEFAULT_PREFIX + "/*"));
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Jersey {@link javax.ws.rs.core.Application} with all the resources
|
||||
* required by the Eureka server.
|
||||
*/
|
||||
@Bean
|
||||
public javax.ws.rs.core.Application jerseyApplication(Environment environment, ResourceLoader resourceLoader) {
|
||||
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false, environment);
|
||||
|
||||
// Filter to include only classes that have a particular annotation.
|
||||
//
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Path.class));
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Provider.class));
|
||||
|
||||
// Find classes in Eureka packages (or subpackages)
|
||||
//
|
||||
Set<Class<?>> classes = Sets.newHashSet();
|
||||
for(String basePackage: EUREKA_PACKAGES) {
|
||||
Set<BeanDefinition> beans = provider.findCandidateComponents(basePackage);
|
||||
for (BeanDefinition bd : beans) {
|
||||
Class<?> cls = ClassUtils.resolveClassName(bd.getBeanClassName(), resourceLoader.getClassLoader());
|
||||
classes.add(cls);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the Jersey ResourceConfig
|
||||
//
|
||||
Map<String, Object> propsAndFeatures = Maps.newHashMap();
|
||||
propsAndFeatures.put(
|
||||
// Skip static content used by the webapp
|
||||
ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX,
|
||||
EurekaServerConfigBean.DEFAULT_PREFIX + "/(fonts|images|css|js)/.*");
|
||||
|
||||
DefaultResourceConfig rc = new DefaultResourceConfig(classes);
|
||||
rc.setPropertiesAndFeatures(propsAndFeatures);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean traceFilterRegistration(
|
||||
@Qualifier("webRequestLoggingFilter") Filter filter) {
|
||||
@@ -71,5 +133,4 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter {
|
||||
bean.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user