How to handle error being thrown by ClusterListenerThread during the instantiation (by Spring) of my Hazelcast Client bean? - hazelcast

I am using Spring to configure a (lazy loaded) Hazelcast Client that connects to a 2 member cluster.
<hz:client id="hazelcast" lazy-init="true">
<hz:group name="${HzName}" password="${HzPassword}"/>
<hz:properties>
<hz:property name="hazelcast.client.connection.timeout">10000</hz:property>
<hz:property name="hazelcast.client.retry.count">600</hz:property>
<hz:property name="hazelcast.jmx">true</hz:property>
<hz:property name="hazelcast.logging.type">slf4j</hz:property>
</hz:properties>
<hz:network smart-routing="true" redo-operation="true" connection-attempt-period="5000"
connection-attempt-limit="2">
<hz:member>${HzMember1}</hz:member>
<hz:member>${HzMember2}</hz:member>
</hz:network>
</hz:client>
My issue is:
If, at the time of my application starting, BOTH of the cluster members happen to be unavailable then I am seeing ClusterListenerThread throwing a SEVERE exception:
WARNING: Unable to get alive cluster connection, try in 4945 ms later, attempt 1 of 2.
16-Apr-2015 14:57:34 com.hazelcast.client.spi.impl.ClusterListenerThread
WARNING: Unable to get alive cluster connection, try in 4987 ms later, attempt 2 of 2.
16-Apr-2015 14:57:39 com.hazelcast.client.spi.impl.ClusterListenerThread
SEVERE: Error while connecting to cluster!
java.lang.IllegalStateException: Unable to connect to any address in the config!
at com.hazelcast.client.spi.impl.ClusterListenerThread.connectToOne(ClusterListenerThread.java:273)
at com.hazelcast.client.spi.impl.ClusterListenerThread.run(ClusterListenerThread.java:79)
Caused by: com.hazelcast.spi.exception.RetryableIOException: java.util.concurrent.ExecutionException: com.hazelcast.core.HazelcastException: java.net.ConnectException: Connection refused
at com.hazelcast.client.connection.nio.ClientConnectionManagerImpl$OwnerConnectionFuture.createNew(ClientConnectionManagerImpl.java:649)
at com.hazelcast.client.connection.nio.ClientConnectionManagerImpl$OwnerConnectionFuture.access$300(ClientConnectionManagerImpl.java:605)
at com.hazelcast.client.connection.nio.ClientConnectionManagerImpl.ownerConnection(ClientConnectionManagerImpl.java:268)
at com.hazelcast.client.spi.impl.ClusterListenerThread.connectToOne(ClusterListenerThread.java:245)
...which subsequently results in my Hazelcast Client bean not being instantiated and therefore everything downstream that relies upon it's existence blowing up as well.
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hazelcast': Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public static com.hazelcast.core.HazelcastInstance com.hazelcast.client.HazelcastClient.newHazelcastClient(com.hazelcast.client.config.ClientConfig)] threw exception; nested exception is java.lang.IllegalStateException: Cannot get initial partitions!
How can I detect and handle the error being thrown by ClusterListenerThread during the instantiation (by Spring) of my Hazelcast Client bean?
nb. I'm frustrated by the fact that the Client bean is not being constructed (despite there being no available members) because I know for a fact that an already constructed Client can handle having all of it's member's become unavailable and will happily start working again when one or more of those members become available again.

What you need to do is configure connectionAttemptLimit and connectionAttemptPeriod.
If you set connectionAttemptLimit to INT_MAX and pick a reasonable connectiontAttemptPeriod, the client will practically try to connect to given memberlist forever every X seconds. This is currently more like a workaround, because when you first open HazelcastClient it will block until one of the members become available. A further workaround, you can try to open the client in another dedicated thread.
About making a fully supported feature, there was a discussion going on by the hazelcast team here.
https://github.com/hazelcast/hazelcast/issues/552
I am adding a question as a reference to the issue.

Related

Unable to start guidewire CC server from tomcat

We have been trying to start the claimcenter server from tomcat. The server is getting started even though it throws exception with the message "ClaimCenter unable to start" in the logs. Please find the log details below.
gw.pl.exception.GWLifecycleException: An exception was thrown while starting a component. Setting runlevel to NODAEMONS
Caused by: gw.pl.exception.GWLifecycleException:Messaging plugin does not implement MessageTransport interface error
Possible causes -
The xyzMessageTransport class failed to instantiate due to invalid parameters.
A class which is not implementation of MessageTransport inteface configured under
MessageTransport plugin. check messaging-config.xml.
Also - specify plugin name or attach whole log if possible.

Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'productRepository';

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-08-05 09:53:05.348 ERROR 46991 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'productRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.example.cassandra.springbootcassandrademo.repository.ProductRepository defined in #EnableCassandraRepositories declared on CassandraRepositoriesRegistrar.EnableCassandraRepositoriesConfiguration: Cannot resolve reference to bean 'cassandraTemplate' while setting bean property 'cassandraTemplate'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.datastax.oss.driver.api.core.CqlSession]: Factory method 'cassandraSession' threw exception; nested exception is com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node(endPoint=/127.0.0.1:9042, hostId=null, hashCode=2fe1348e): [com.datastax.oss.driver.api.core.connection.ConnectionInitException: [s0|control|connecting...] Protocol initialization request, step 1 (OPTIONS): failed to send request (java.nio.channels.ClosedChannelException)]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
From your error message the problem is that it cannot find the cassandra instance running on localhost.
Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node(endPoint=/127.0.0.1:9042, hostId=null, hashCode=2fe1348e)
If your host is somewhere other than localhost, you'll need to set the spring.data.cassandra.contact-points in your configuration file or set up a bean to create the Cassandra Cluster or Session (depending on which version of Spring boot you are using).
I faced the same issue today. In my case may be it was some internal issue of spring boot itself. I Solved by changing the spring-boot version in pom.xml.
It was
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/>
</parent>
I changed the version to
<version>2.0.2.RELEASE</version>
And it worked.

Fail to start application locally after enabling Spring Security

I am trying to enable spring security to protect my backend services in SDK archetype project based on Spring according to the tutorial https://blogs.sap.com/2017/07/18/step-7-with-sap-s4hana-cloud-sdk-secure-your-application-on-sap-cloud-platform-cloudfoundry/.
After I start the application locally, an error message shows up - "Environment variable VCAP_SERVICES not set". Below is the stack trace of this error.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration': Unsatisfied dependency expressed through field 'tokenServices'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceServerTokenServices' defined in class path resource [com/bosch/SecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.provider.token.ResourceServerTokenServices]: Factory method 'resourceServerTokenServices' threw exception; nested exception is java.lang.IllegalStateException: Environment variable VCAP_SERVICES not set
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1378)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.bosch.Application.main(Application.java:23)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceServerTokenServices' defined in class path resource [com/bosch/SecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.provider.token.ResourceServerTokenServices]: Factory method 'resourceServerTokenServices' threw exception; nested exception is java.lang.IllegalStateException: Environment variable VCAP_SERVICES not set
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:625)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:455)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1455)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1419)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1338)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 19 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.provider.token.ResourceServerTokenServices]: Factory method 'resourceServerTokenServices' threw exception; nested exception is java.lang.IllegalStateException: Environment variable VCAP_SERVICES not set
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:620)
... 35 common frames omitted
Caused by: java.lang.IllegalStateException: Environment variable VCAP_SERVICES not set
at com.sap.xs2.security.commons.SAPVcapServicesParser.parseVcapServices(SAPVcapServicesParser.java:42)
at com.sap.xs2.security.commons.SAPVcapServicesParser.<init>(SAPVcapServicesParser.java:30)
at com.sap.xs2.security.commons.SAPPropertyPlaceholderConfigurer.<init>(SAPPropertyPlaceholderConfigurer.java:35)
at com.sap.xs2.security.commons.SAPOfflineTokenServicesCloud.<init>(SAPOfflineTokenServicesCloud.java:27)
at com.bosch.SecurityConfig.resourceServerTokenServices(SecurityConfig.java:47)
at com.bosch.SecurityConfig$$EnhancerBySpringCGLIB$$5e72219b.CGLIB$resourceServerTokenServices$1(<generated>)
at com.bosch.SecurityConfig$$EnhancerBySpringCGLIB$$5e72219b$$FastClassBySpringCGLIB$$948b0fba.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at com.bosch.SecurityConfig$$EnhancerBySpringCGLIB$$5e72219b.resourceServerTokenServices(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 36 common frames omitted
The steps to reproduce the issue:
Create a fresh sdk archetype project based on Spring
Uncomment out all the code in SecurityConfig.java
Import all the security libraries
Start the application locally
The application is running well on SCP Cloud Foundry.
I know the root cause is the application is going to read Environment variable VCAP_SERVICES when initializing bean in SecurityConfig.java. But it cannot find it in local environment.
Is there any workaround if I want to run application locally?
Update:
I just found out that we had a comparable question with an helpful answer before: How to run downloaded App Router via Service Marketplace
As the security features heavily rely on the bound XSUAA service, as well as the fact that you need to access your application via an AppRouter, there is no easy/recommended way to start a secured application locally.
One option, we've used extensively is to use a script locally which sets the VCAP_SERVICES environment variable similar like on Cloud Foundry (cf env ). I assume, this will satisfy the SAPOfflineTokenServicesCloud bean creation.
With that you can start the application locally, but NOT test your web application when the application is secured. Because in this case you need to call the endpoints of your web application with an Authorization header, which needs to contain a "valid" access token. A token is considered to be valid if it is not expired and if it is signed with a private RSA key, which matches the public RSA key, which is provided by the jwks token endpoint of the uaa as documented here: https://docs.cloudfoundry.org/api/uaa/version/74.4.0/index.html#token-keys
You have these options:
For integration testing, you can fetch a fresh access token for your (test) user from the xsuaa service using this endpoint: https://docs.cloudfoundry.org/api/uaa/version/74.4.0/index.html#password-grant. You can use also the java token-client lib.
For local testing (w/o) Xsuaa interaction:
you need to generate a Jwt token using for example this JwtGenerator and
change as part of your VCAP_SERVICES environment your verificationkey, which matches to the private key, the token is signed with (e.g. the JwtGenerator's public key), e.g. "verificationkey":"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BA...".
For unit testing
you need to generate a Jwt token using for example this JwtGenerator and
you need to overwrite your SAPOfflineTokenServicesCloud as done here
This should work (I've never tested that setup in combination with SAP Cloud SDK).

Amazon SQS Outbound channel adapter won't initialize

I'm trying to start up a spring-int-aws flow that is writing to an SQS queue, but the context won't load.
Error starting ApplicationContext. To display the auto-configuration report
re-run your application with 'debug' enabled.
2016-10-03 14:10:51.848 ERROR 3741 --- [ main]
o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'org.springframework.integration.aws.outbound.SqsMessageHandler#0':
Bean instantiation via constructor failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to instantiate
[org.springframework.integration.aws.outbound.SqsMessageHandler]: Constructor
threw exception; nested exception is java.lang.NoSuchMethodError:
org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate.<init
(Lcom/amazonaws/services/sqs/AmazonSQS;Lorg/springframework/cloud/aws/core/env/ResourceIdResolver;)V
....
Did some research: Inside of the SQSMessageHandler (v 1.0.0-RELEASE) it's attempting to create a QueueMessagingTemplate using a declared AmazonSQS object, however the QueueMessagingTemplate (v1.1.3 Release) it requires an AmazonSQSAsync object in the constructor. Since spring-cloud-aws uses the sub-interface, it seems that spring-int-aws should as well.
Am I missing something, or should this be an issue filed against the project?
spring-integration-aws is built against 1.1.1.
Please open an issue there so we can make a compatible build.
That said, it's pretty unusual for Spring projects to break APIs in a point release, so we should raise an issue for spring-cloud-aws too, to ask them to restore the other ctor (if possible), and cross-link the issues.
I opened issues.
We would wait for the disposition of that issue before doing anything in spring-integration-aws (but we should still go ahead and support the async option).

Replication exception with WebSphere 7 sessions

I have a JSF 2 + Spring 3 application that's currently being deployed to a clustered WebSphere 7 environment. The servers are configured for memory-to-memory replication for session handling. While running tests on the application, a common exception that's being generated is the following:
[1/3/12 20:34:48:784 EST] 0000003c WASSession E MTMBuffWrapper storeObject SESN0200E: Caught Exception while trying to serialize.
[1/3/12 20:34:48:785 EST] 0000003c WASSession E MTMHashMap handlePropertyHits SESN0202E: Failed to replicate attribute com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap
Any idea as to what this means and how to resolve it? Thanks.
All objects on the session have to be Serializable for memory-to-memory replication (or database persistence) to work. Apparently the specified one is not.
(Hint, you can usually Google on the specific error code, which usually will send you to one of the official WebSphere InfoCenter pages.)

Resources