问题
The correct dependencies for my gradle.build are driving me crazy!
In order to access an Apache Geode 1.10 server, I am using:
// Geode client dependency
implementation 'org.springframework.geode:spring-geode-starter:1.2.13.RELEASE'
implementation 'org.springframework.data:spring-data-geode:2.2.12.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-tomcat:2.2.13.RELEASE'
This fails with the error:
org.springframework.context.support.AbstractApplicationContext 596 refresh:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'ClusteredSpringSessions' defined in class path resource
[org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
What is there to tell me the dependency missing for the UnsatisfiedDependencyException
for 'ClusteredSpringSessions'
?
If I remove the @EnableGemFireHttpSession
annotation then I get the error
2021-02-02T19:29:49,011 WARN [main] org.springframework.context.support.AbstractApplicationContext 596 refresh:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/data/gemfire/cache/config/GemfireCachingConfiguration.class]:
Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
What is there to tell me the dependency missing for the UnsatisfiedDependencyException
for 'cacheManager'
?
Thanks
UPDATE The App is run like Spring Boot @ComponentScan finds candidate component class but does not inject @Configuration beans but more specifically
@SpringBootApplication
@ComponentScan({"api", "rsocket", "pricing", "listeners", "dealing", "web"}) // scans packages for @ components
@EnableLogging(logLevel="debug", logFile="geodeApi.log")
public class Api {
private static final Logger log = LogManager.getLogger(Api.class);
public static void main(String[] args) {
log.info("In Main");
SpringApplication app = new SpringApplication(Api.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Api.class, args);
log.info("Out Main");
}
}
The component scan finds various @Component
annotated classes for example
@Component
@EnableClusterDefinedRegions(clientRegionShortcut=ClientRegionShortcut.PROXY)
public class ClientCache {
private static final Logger log = LogManager.getLogger(ClientCache.class);
@Resource
private Region<String, String> admin;
@Autowired
LQuote lQuote;
@Autowired
LReject lReject;
@Autowired
LDeal lDeal;
@Autowired
DealNumber dealNumber;
@Autowired
PriceService priceService;
@PreDestroy
public void onDestroy() throws Exception {
log.info("onDestroy");
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
admin.put(guid, "API Shutdown");
// TODO: Cancel all open quote streams
log.traceExit();
}
@Bean
ApplicationRunner StartedUp(){
log.traceEntry("StartedUp");
return args -> {
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
admin.put(guid, "API Started");
lQuote.addListener();
lReject.addListener();
lDeal.addListener();
// Get latest deal number
int currentId = dealNumber.readCurrentId();
// Set it + 1 in case the web server was reboot on the fly
priceService.setCurrentId(currentId + 1);
log.traceExit();
};
}
回答1:
Technically, it is not necessary to explicitly declare the SDG dependency.
The SBDG dependency (i.e. org.springframework.geode:spring-geode-starter
) already includes SDG (org.springframework.data:spring-data-geode
). You can follow the dependency trail starting here, then here and finally, here.
As the Version Compatibility Matrix for SBDG specifies, SBDG 1.2.13.RELEASE
specifically includes, and is based on, SDG 2.2.12.RELEASE
(already), which is (technically) based on Apache Geode 1.9.2
.
However, if you need to use Apache Geode 1.10
, then you could (recommended) simply declare dependency management to enforce the use of Apache Geode 1.10
in your Gradle build:
plugins {
id 'org.springframework.boot' version '2.2.13.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
dependencyManagement {
dependencies {
dependency 'org.apache.geode:geode-core:1.10.0'
dependency 'org.apache.geode:geode-cq:1.10.0'
dependency 'org.apache.geode:geode-lucene:1.10.0'
dependency 'org.apache.geode:geode-wan:1.10.0'
}
}
dependencies {
implementation 'org.springframework.geode:spring-geode-starter:1.2.13.RELEASE`
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
}
...
WARNING: SDG
2.2.12.RELEASE
is officially based on Apache Geode1.9.2
, and though it should work reasonably well with Apache Geode1.10
, there could expectedly be limitations in certain use cases.
This is not unlike what Spring Initializer conveniently generates for you. Of course, Spring Initializer now uses the new SBDG BOM that makes managing individual SBDG module dependencies even easier, which is not unlike how Spring Boot's dependency management manages transitive dependencies, including 3rd party libs.
Regarding the Exceptions...
It really seems to me like you are having configuration problems rather than dependency problems, actually.
Of course, it is hard to say for certain given you shared very minimal Gradle build configuration and no code snippets from your Spring Boot application configuration, only mentions and what I am able to derive from the Exception messages. So, for now, I'll proceed based on what you provided and what I know or could derive.
Looking at this part of the (first) Exception message:
Error creating bean with name 'ClusteredSpringSessions' defined in class path resource
[org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0
And, specifically:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0
This message refers to the (Spring Java) configuration provided by SSDG and imported/auto-configured by SBDG.
The "Unsatisfied dependency", or "parameter 0", is the 1st method parameter in the sessionRegion(..)
(Spring JavaConfig-based) @Bean
definition method declared in SSDG's configuration. It is the dependency on the GemFire cache instance (e.g. ClientCache
) required to create the "ClusteredSpringSessions" Region
.
So now, the question becomes, how is the cache created?
Well, this is what the framework is trying to do next... resolve the cache bean dependency (instance reference), which necessary triggers the cache creation first (due to dependency order)...
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError
We see that an IllegalAccessError
occurred (O.o) which already smells like a version problem to me, but...
The ClientCacheConfiguration
is provided by SDG.
Finally, we arrive at the underlying cause...
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
NOTE:
ClientCacheConfiguration
extendsAbstractCacheConfiguration
, which extendsAbstractAnnotationConfigSupport
, and therefore should have "access" to the protectedhasValue(:Number)
method.
The main Thread appears to be in one of these Lambdas where the AbstractAnnotationConfig.hasValue(:Number)
method is used.
I am no entirely sure what this means...
org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app'
Are you possibly using Spring Boot's new (Layered) Docker Image support by chance?
The 2nd Exception message (involving the cacheManager
bean this time) leads to the same outcome, actually. It is no different, but simply involves another bean (i.e. cacheManager
bean) with the same dependency on the cache instance:
Error creating bean with name 'cacheManager' defined in class path resource
[org/springframework/data/gemfire/cache/config/GemfireCachingConfiguration.class]
: Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
And, specifically:
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
tried to access protected method 'boolean org.springframework.data.gemfire
.config.annotation.support.AbstractAnnotationConfigSupport
.hasValue(java.lang.Number)'
And:
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
are in unnamed module of loader 'app')
I am not familiar with this error messages (basically, said class(es) "are in unnamed module of loader 'app'.") What?
How is this Spring Boot app being run?
Definitely providing a sample app, one or more tests, your configuration, logs, Stack Traces in addition to Exception messages, setup, runtime environment, etc, etc, will go along way in trying to understand the context of this problem.
At this point, I am really trying to point you in a direction to start untangling the problem.
Sorry, I cannot (currently) be of more help in this case.
回答2:
A lot of the problem was using Java JDK version 15. The correct versions require Java 11.
// Geode client dependency
implementation 'org.springframework.geode:spring-geode-starter:1.2.8.RELEASE'
implementation 'org.springframework.data:spring-data-geode:2.2.8.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
来源:https://stackoverflow.com/questions/66016442/spring-boot-geode-unsatisfied-dependency-expressed-through-method-sessionregion