Comments (6)
This "problem" is caused by Apache Geode itself (!), in version 1.9
.
SBDG 1.2
is based on Spring Boot 2.2
, where both SBDG 1.2
and Spring Boot 2.2
are based on SD[G] Moore/2.2
, which is based on Apache Geode 1.9.0
(currently).
Apache Geode 1.9
transitively pulls in the javax.servlet:javax.servlet-api
given that it declares a compile-time dependency on org.eclipse.jetty:jetty-server
:
$ gradlew :spring-geode:dependencies | less
...
+--- org.apache.geode:geode-core:1.9.0
| +--- com.github.stephenc.findbugs:findbugs-annotations:1.3.9-1
| +--- org.jgroups:jgroups:3.6.14.Final
| +--- antlr:antlr:2.7.7
...
| +--- org.eclipse.jetty:jetty-server:9.4.12.v20180830 -> 9.4.19.v20190610
| | +--- javax.servlet:javax.servlet-api:3.1.0 -> 4.0.1
| | +--- org.eclipse.jetty:jetty-http:9.4.19.v20190610
| | | +--- org.eclipse.jetty:jetty-util:9.4.19.v20190610
| | | \--- org.eclipse.jetty:jetty-io:9.4.19.v20190610
| | | \--- org.eclipse.jetty:jetty-util:9.4.19.v20190610
| | \--- org.eclipse.jetty:jetty-io:9.4.19.v20190610 (*)
from spring-boot-data-geode.
SBDG cannot add an exclusion on org.eclipse.jetty:jetty-server
in the starters since this will cause an Exception on shutdown of an Apache Geode/Pivotal GemFire (client or peer) cache instance...
2019-08-21 00:44:32.819 WARN 63204 --- [m shutdown hook] o.a.g.d.i.InternalDistributedSystem : Exception trying to close cache
java.lang.BootstrapMethodError: java.lang.IllegalAccessError: no such method: org.apache.geode.internal.cache.HttpService.stop()void/invokeVirtual
at org.apache.geode.internal.cache.GemFireCacheImpl.close(GemFireCacheImpl.java:2183) ~[geode-core-1.9.0.jar:na]
at org.apache.geode.distributed.internal.InternalDistributedSystem.disconnect(InternalDistributedSystem.java:1627) [geode-core-1.9.0.jar:na]
at org.apache.geode.distributed.internal.InternalDistributedSystem.lambda$static$4(InternalDistributedSystem.java:2278) [geode-core-1.9.0.jar:na]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_192]
Caused by: java.lang.IllegalAccessError: no such method: org.apache.geode.internal.cache.HttpService.stop()void/invokeVirtual
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:483) ~[na:1.8.0_192]
... 4 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/eclipse/jetty/server/Handler
at java.lang.invoke.MethodHandleNatives.resolve(Native Method) ~[na:1.8.0_192]
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975) ~[na:1.8.0_192]
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000) ~[na:1.8.0_192]
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394) ~[na:1.8.0_192]
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750) ~[na:1.8.0_192]
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477) ~[na:1.8.0_192]
... 4 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.server.Handler
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_192]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_192]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_192]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_192]
... 10 common frames omitted
Therefore, it is unclear to me whether the Apache Geode node shuts down cleanly under these circumstances.
As such, I strongly recommend that the Apache Geode community fix this issues by:
- Making the Eclipse Jetty dependency "optional" in Apache Geode core (i.e.
geode-core
), and... - Not expect or require the user to have to declare the Eclipse Jetty dependency on the application classpath, and...
- Ensure that an Apache Geode cache instance is shutdown properly when Eclipse Jetty is not on the classpath.
Jetty is only used by Apache Geode Locator/Managers and Servers to implement the embedded HTTP service, which hosts the Developer REST API, and Management (Admin) REST API and/or Pulse, respectively.
Jetty is never needed and used on the client-side of a GemFire/Geode cache node (e.g. ClientCache
instance), which makes the problem noted in the previous comment even worse (!) since SBDG focuses on auto-configuring a ClientCache
instance, by default!
from spring-boot-data-geode.
Given the information above, I have filed GEODE-7107 to resolve this "Apache Geode problem" properly, where it belongs!
from spring-boot-data-geode.
I see that GEODE-7107 is already in progress for including a fix.
See comment for more details.
from spring-boot-data-geode.
After review, it turns out the comment referencing the commit is not a fix!
See the followup comment for further details.
from spring-boot-data-geode.
To recap the problem:
- First, when a Spring Boot project using Apache Geode is created with Spring Initializer, it currently declares the following SBDG starter dependency for you:
<dependency>
<groupId>org.springframework.geode</groupId>
<artifactId>spring-geode-starter</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
</dependency>
If you try to run the provided app, you will hit an Exception:
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:156) ~[spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-5.2.0.RC1.jar:5.2.0.RC1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:746) [spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:396) [spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1225) [spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214) [spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.example.app.springgeodeapp.SpringGeodeAppApplication.main(SpringGeodeAppApplication.java:10) [classes/:na]
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:203) ~[spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179) ~[spring-boot-2.2.0.M5.jar:2.2.0.M5]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153) ~[spring-boot-2.2.0.M5.jar:2.2.0.M5]
... 8 common frames omitted
This is because geode-core
pulls in jetty-server
, which pulls in the javax.servlet-api
:
$ gradlew :spring-geode:dependencies | less
...
+--- org.apache.geode:geode-core:1.9.0
| +--- com.github.stephenc.findbugs:findbugs-annotations:1.3.9-1
| +--- org.jgroups:jgroups:3.6.14.Final
| +--- antlr:antlr:2.7.7
...
| +--- org.eclipse.jetty:jetty-server:9.4.12.v20180830 -> 9.4.19.v20190610
| | +--- javax.servlet:javax.servlet-api:3.1.0 -> 4.0.1
| | +--- org.eclipse.jetty:jetty-http:9.4.19.v20190610
| | | +--- org.eclipse.jetty:jetty-util:9.4.19.v20190610
| | | \--- org.eclipse.jetty:jetty-io:9.4.19.v20190610
| | | \--- org.eclipse.jetty:jetty-util:9.4.19.v20190610
| | \--- org.eclipse.jetty:jetty-io:9.4.19.v20190610 (*)
As I stated already, Jetty should be an "optional" dependency in Apache Geode since 1) it is server-side specific (Locators, Managers and Servers) in order to implement the embedded HTTP service that hosts the Developer/Management REST APIs and Pulse, and 2) Jetty is simply not required to properly run a Locator, Manager or Server since starting the embedded HTTP service is optional.
- However, if I try to only "exclude" the Jetty dependency from the SBDG starter:
<dependency>
<groupId>org.springframework.geode</groupId>
<artifactId>spring-geode-starter</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
</exclusions>
</dependency>
NOTE: Previously, I incorrectly thought I needed to exclude the
org.springframework:spring-web
dependency as well, because I thought thatspring-web
also caused Spring Boot to determine the application was a "Web application" whenspring-web
was on the application classpath. However, this thinking was incorrect, as @snicole pointed out, because it is only the presence of thejavax.servlet-api
that causes Spring Boot to decide that the application is a Web application, thereby causing an embedded Servlet Container to be bootstrapped by Spring Boot on application startup. As an additional side note,spring-web
already appropriately marks thejavax.servlet-api
dependency as "optional", sospring-web
cannot cause this issue. Only Apache Geode is causing this issue!
However, the exclude on jetty-server
leads to the following Exception when the Apache Geode cache instance (client or peer) is shutdown:
java.lang.BootstrapMethodError: java.lang.IllegalAccessError: no such method: org.apache.geode.internal.cache.HttpService.stop()void/invokeVirtual
at org.apache.geode.internal.cache.GemFireCacheImpl.close(GemFireCacheImpl.java:2183) ~[geode-core-1.9.0.jar:na]
at org.apache.geode.distributed.internal.InternalDistributedSystem.disconnect(InternalDistributedSystem.java:1627) [geode-core-1.9.0.jar:na]
at org.apache.geode.distributed.internal.InternalDistributedSystem.lambda$static$4(InternalDistributedSystem.java:2278) [geode-core-1.9.0.jar:na]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_192]
Caused by: java.lang.IllegalAccessError: no such method: org.apache.geode.internal.cache.HttpService.stop()void/invokeVirtual
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:483) ~[na:1.8.0_192]
... 4 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/eclipse/jetty/server/Handler
at java.lang.invoke.MethodHandleNatives.resolve(Native Method) ~[na:1.8.0_192]
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975) ~[na:1.8.0_192]
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000) ~[na:1.8.0_192]
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394) ~[na:1.8.0_192]
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750) ~[na:1.8.0_192]
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477) ~[na:1.8.0_192]
... 4 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.server.Handler
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_192]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_192]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_192]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_192]
... 10 common frames omitted
- Finally, I tried simply excluding the transitive dependency,
javax.servlet:javax.servlet-api
from SBDG'sspring-geode-starter
, and Lo and behold, that app starts and shuts down successfully!
<dependency>
<groupId>org.springframework.geode</groupId>
<artifactId>spring-geode-starter</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
This exclusion does not seem to present any problems for an Apache Geode cache on shutdown, either. \o/
As such, the targeted (temporary/workaround) fix for this Issue will be to include an exclusion on the javax.servlet:javax.servlet-api
in the SBDG starters, at least until GEODE-7107 is properly addressed!
from spring-boot-data-geode.
Related Issues (20)
- Create a spring-cloud-bindings BindingsPropertiesProcessor for Apache Geode HOT 2
- State project goals in documentation
- Include chapter on Testing in the SBDG reference documentation
- Compatability matrix is not up to date. HOT 1
- Remove link to SDG Version Compatibility Matrix in SBDG Wiki
- Missing geode-pulse Dependency in Documentation
- Compatibility question HOT 3
- Using a sealed class as a data object fails HOT 1
- Inheriting from entity types causes failure when using entity-defined Regions HOT 1
- Exception thrown when parsing spring.session.timeout property with java.time.Duration styling HOT 1
- Improve documentation around overriding dependency versions
- Clarify the use of SDG's @EnableExpiration annotation in docs
- Integrate Apache Geode and Jetty 11 HOT 1
- Improve Logging configuration in the Starter
- @LocatorApplication does not work with @EnableSecurity HOT 5
- PARTITION_PERSISTENT_OVERFLOW index slow HOT 6
- SBDG Fails in Docker HOT 10
- Gemfire Fails in AWS ECS HOT 8
- Add new BeanPostProcessor to register RegionConfigurers for explicitly declared Region beans
- Improve logging output for @EnableClusterAware functionality re:connection type HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-boot-data-geode.