OK - problem ==> 2 Datasources (or more) will cause an error when using Springboot Session.
I have a Springboot project, with different data sources for different purposes. So within said project I would like to have Spring replace the HttpSession, with the Spring-Session module's HttpSession.
The creation of the session tables is simple if you follow the guides.
But the guides and API docs say you need JUST one data source. And so, since I have 2 or more I get the following error:
2020-07-21 21:38:59.134 ERROR 171262 --- [ restartedMain] o.s.b.web.embedded.tomcat.TomcatStarter :
Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException.
Message: Error creating bean with name 'sessionRepositoryFilterRegistration' defined in class path resource
[org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRepositoryFilterRegistration' parameter 1;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with
name 'org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'javax.sql.DataSource' available:
expected single matching bean but found 2: authModelDs,secureSessionDS
So since it cannot decide which one to use, I have to manually configure it, except that the entire process leads you to a class called
org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration, which is quite literally non-configurable under the given need to set your own datasource.
I have looked a bit around, and there is no way to configure the Session Filter, once it is created to replace the datasource there too.
So I am boggled: how can I set the correct datasource for the configured Spring-Session?
Any help would be appreciated.
AHA! Soooooo
There is an annotation that you can place on the Bean creation of your datasource, to specify that such a bean is the SpringBoot session datasource.
The annotation is - #SpringSessionDataSource
It is not something that is really straight forward in the documentation at all!
Props to the following Stack Overflow answer:
Spring Boot and Spring Session: How to control the DataSource
I'm trying to use Spring Cloud's AWS SQS in a project I'm working on. At this time, I'm only running the application locally on my dev machine. Thus, what I want is to connect to the SQS on AWS without having to deploy my app to an EC2 instance.
However, it seems like the AWS SDK used in Spring Cloud's AWS package will attempt to authenticate through metadata and wants to resolve 169.254.169.254/latest/meta-data/instance-id. Since I'm still the running the app locally, the endpoint cannot be resolved and an error is thrown:
2019-12-29 16:38:27.420 WARN 22462 --- [ restartedMain] com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). Failed to connect to service endpoint:
com.amazonaws.SdkClientException: Failed to connect to service endpoint:
at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:70) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:75) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:62) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:400) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:369) ~[aws-java-sdk-core-1.11.699.jar:na]
at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38) ~[spring-cloud-aws-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.cloud.aws.context.annotation.OnAwsCloudEnvironmentCondition.matches(OnAwsCloudEnvironmentCondition.java:37) ~[spring-cloud-aws-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:221) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:587) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
...
I've tried to explicitly supply an SQS endpoint in my bean, but it still attempts to connect to 169.254.169.254 resulting in the error above:
public AmazonSQSAsync sqsClient() {
EndpointConfiguration endpointConfig = new AwsClientBuilder.EndpointConfiguration(
"sqs.us-east-1.amazonaws.com",
"us-east-1"
);
return AmazonSQSAsyncClientBuilder
.standard()
.withEndpointConfiguration(endpointConfig)
.withCredentials(new AWSStaticCredentialsProvider(new DefaultAWSCredentialsProviderChain().getCredentials()))
.build();
}
Although I'm not certain about this, I suspect that the error is occurring because I'm running the app locally on my dev machine and so it couldn't resolve to the endpoint. But I'm not entirely sure about this too because I'm running other AWS services in the same app using the AWS SDK and I don't have this error.
I've the following dependencies in my pom.xml and it appears that having any one of them will cause the error to occur. That's, I don't even have to create the beans to have that error. Adding these dependencies will immediately, for some reason, causes the SDK to attempt to resolve that endpoint and fail with that error.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws-messaging</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
What else should I do to fix the error that it failed to connect to service endpoint?
I have received below errors when running Spring Boot Project for AWS SNS
i.InstanceMetadataServiceResourceFetcher : Fail to retrieve token
com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/dynamic/instance-identity/document). Failed to connect to service endpoint:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Unsatisfied dependency expressed through method 'stackResourceRegistryFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonCloudFormation' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is no EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance
Error creating bean with name 'org.springframework.cloud.aws.core.env.ResourceIdResolver.BEAN_NAME': Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Unsatisfied dependency expressed through method 'stackResourceRegistryFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonCloudFormation' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is no EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance
Resolution applied:
Add below code snippet to SpringBootApplication & Click on Run Button in the IDE
#SpringBootApplication(
exclude = {
org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class
}
)
I know many people have already explained what's issue and how to skip this error. But, all the above method didn't work for me. Finally after lot of search I set following aws configuration property and it worked for me.
cloud.aws.region.use-default-aws-region-chain=true
cloud.aws.stack.auto=false
cloud.aws.credentials.access-key=
cloud.aws.credentials.secret-key=
cloud.aws.region.auto=false
cloud.aws.region.static=
cloud.aws.stack=false
logging.level.com.amazonaws.util.EC2MetadataUtils=error
logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error
The following configuration worked for me:
cloud:
aws:
region:
auto: false
static: eu-west-1
use-default-aws-region-chain: true
stack: false
stack.auto: false
logging:
level:
com:
amazonaws:
internal:
InstanceMetadataServiceResourceFetcher: error
util:
EC2MetadataUtils: error
When using the AWS Java SDK outside of an EC2 instance, you can disable loading credentials or regions from EC2 Metadata instance service with a System property or an Environment variable.
System Property : com.amazonaws.sdk.disableEc2Metadata
Environment variable : AWS_EC2_METADATA_DISABLED
However, you will still get a warning at application startup, it tells you the EC2Metadata is disabled by configuration : "EC2 Instance Metadata Service is disabled"
2020-03-27 18:10:42.483 WARN 71123 --- [main] com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). EC2 Instance Metadata Service is disabled
com.amazonaws.AmazonClientException: EC2 Instance Metadata Service is disabled
at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:65)
at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:66)
at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:402)
at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:371)
at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)
...
Fix the problem adding in the application.yaml file:
logging:
level:
com:
amazonaws:
util:
EC2MetadataUtils: error
As far as I understand its trying to check if your application is running on cloud environment, from the 5th last line of the stacktrace
org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)
I checked out the the repo and here is the code snippet -
public static boolean isRunningOnCloudEnvironment() {
if (isCloudEnvironment == null) {
try {
isCloudEnvironment = EC2MetadataUtils
.getData(EC2_METADATA_ROOT + "/instance-id", 1) != null;
}
catch (AmazonClientException e) {
isCloudEnvironment = false;
}
}
return isCloudEnvironment;
}
As per the snippet it tried to fetch instance metadata and if it fails it return false, which means you are not on the Cloud Environment. However this code is expected to Catch AmazonClientException but the stacktrace you shared is throwing SdkClientException exception, which this part of the snippet can't catch and hence can't return false that you are not on a cloud environment.
Seems like some issue with this build of the library, As per the stacktrace you are using 2.2.1.RELEASE1 which was released 9 days back only. Could you please try to use one of the older version and then report if you are still facing the same issue.
Or as a temporary fix you can try tunnelling to your VPC's entry server. You can use sshuttle for tunnelling purpose if you want. This will mostly make that IP reachable from local machine as well.
I was getting same kind of error when running s3 bucket in spring boot i solved using different location used while creating bucket:
return AmazonS3ClientBuilder
.standard()
.withRegion("us-east-1") //This is the code i added to fix
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
Set cloud.aws.region.auto property to false in Spring application properties (or via environment variables etc.).
Define cloud.aws.region.static property.
This will tell Spring not to use automatic detection based EC2 meta data. Some details.
You may need to configure credentials similarly, you can find related info in the same doc.
The issue is with the spring-cloud version Hoxton.SR8. Replace your spring-cloud version in your pom.xml with Finchley.SR1.
I also faced similar error but not from the Spring cloud. When i added below configuration in application.properties, error went away.
logging.level.com.amazonaws.util.EC2MetadataUtils=error
logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error
But i'm facing some other issues while opening s3a path. Then i printed the stacktrace of the exception and then i got below error
Caused by: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [BasicAWSCredentialsProvider: Access key or secret key is null, WebIdentityTokenCredentialsProvider: You must specify a value for roleArn and roleSessionName, EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), com.amazonaws.auth.InstanceProfileCredentialsProvider#7700439a: Failed to connect to service endpoint: ]
Already credentials are there /.aws folder but not sure why application still giving the error. Fixed by creating environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_KEY and AWS_SESSION_TOKEN
This was coming from an internal dependency at my company, so I couldn't get any of the previously posted solutions to work. What worked for me was to simply set in my environment variables AWS_REGION = 'us-east-1'.
We are creating a new Spring Boot project and a part of it needs multi-threading operation. We are trying to use the ManagedExecutorService, so we declared it as follows:
#Resource(name="java:comp/DefaultManagedExecutorService")
private ManagedExecutorService mes;
And during execution returned the error:
Injection of resource dependencies failed; nested exception is
org.springframework.beans.factory.BeanDefinitionStoreException:
Invalid bean definition with name 'java:comp/DefaultManagedExecutorService' defined in JNDI environment: JNDI lookup failed; nested exception is
javax.naming.NoInitialContextException: Need to specify class name in
environment or system property, or as an applet parameter, or in an
application resource file: java.naming.factory.initial
Does this means that Spring Boot does not support/allow us to use the ManagedExecutorService in tomcat?
I am attempting to convert an existing spring weblogic application to a spring boot embedded tomcat application.
There are lots of moving parts so it's hard to show any code, I'm hoping there is some general answer that might clue me in to the issue.
Under weblogic, using the spring-framework 4.3.6.RELEASE libraries, the application deploys fine. It has no problems creating the different service, repository and component beans.
However, when I migrate it to Spring Boot 1.5.1.RELEASE, I get the following error:
2017-06-21 17:08:16,402 [ERROR] SpringApplication reportFailure (815) - Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'alertEventServiceImpl': Unsatisfied dependency expressed through field 'alertEventDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'alertEventDaoImpl' defined in URL [jar:file:/Users/username/Development/source/carma-war/target/carma-war-2.0.0-SNAPSHOT.war!/WEB-INF/lib/protocol-manager-1.8.0-SNAPSHOT.jar!/org/ihc/hwcir/protocol/dao/AlertEventDaoImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl
Many of our service classes are final as they shouldn't be extended. Since there are so many that are final, I wanted to minimize the amount of code in our different libraries that we modify to make this work.
I thought because the bean creation process works under weblogic, it should work under spring boot.
Things I have tried to force not using the cglib proxies:
All implementations implement interfaces already
In beans created via xml, added <aop:scoped-proxy proxy-target-class="false"/>
In beans created through annotations, added (example for service bean)
#Service
#Scope(proxyMode = ScopedProxyMode.INTERFACE)
However, in the end, I'm perplexed as to why spring can create beans (the classes marked as final) under the weblogic container but unable to do so under the embedded tomcat spring-boot container.
Spring Boot by default uses class based proxies, which will not work with final classes/methods.
To disable this add spring.aop.proxy-target-class=false to the application.properties to enable JDK Dynamic Proxies instead of class based proxies. (And revert your modifications).
NOTE: To have everything take into account the spring.aop.proxy-target-class you might need to upgrade to Spring Boot 1.5.3 as some final patches where made to include this property in parts that were missed in previous versions.
See the following issues for more information 8434, 8869 and 8887.
I was unable to make this work using M. Deinums' answer using spring.aop.proxy-target-class=false.
What worked for me was to add in the application.properties file
spring.dao.exceptiontranslation.enabled=false
Please note that this option disables proxy creation for repositories.
And in my spring boot application configurer the annotation to handle transactions without using a proxy class.
#EnableTransactionManagement(proxyTargetClass = false)
This is using Spring Boot version 1.5.1.RELEASE.
I have set up ActiveMQ as an embedded broker (from this tutorial), and now I want to add a new application, in a different EAR, which needs a new queue.
Has anyone been able to do this?
If I try making two resource adapters in my standalone.xml, they end up using the same broker-config, and I get the error below. So that doesn't seem right.
Error creating bean with name 'org.apache.activemq.xbean.XBeanBrokerService#0' defined in class path resource [broker-config.xml]: Invocation of init method failed; nested exception is javax.management.InstanceAlreadyExistsException: org.apache.activemq:type=Broker,brokerName=brokerOne