diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc
index de4c2169..da9a9a3e 100644
--- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc
@@ -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]
-----
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- com.netflix.eureka
- eureka-core
-
-
- com.netflix.eureka
- eureka-client
-
-
-
-
-----
-
-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]
====
diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml
index 35d40be6..17e7c488 100644
--- a/spring-cloud-netflix-eureka-server/pom.xml
+++ b/spring-cloud-netflix-eureka-server/pom.xml
@@ -57,7 +57,6 @@
com.sun.jersey
jersey-server
- runtime
com.netflix.eureka
diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java
index f30146b4..1264d650 100644
--- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java
+++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java
@@ -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> classes = Sets.newHashSet();
+ for(String basePackage: EUREKA_PACKAGES) {
+ Set beans = provider.findCandidateComponents(basePackage);
+ for (BeanDefinition bd : beans) {
+ Class> cls = ClassUtils.resolveClassName(bd.getBeanClassName(), resourceLoader.getClassLoader());
+ classes.add(cls);
+ }
+ }
+
+ // Construct the Jersey ResourceConfig
+ //
+ Map 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;
}
-
}