Spring Data Startup Exception Handling - java

How would I catch an exception thrown by Spring after failing to connect to the database during startup? I'd like to make the error message user-friendly.
For example, if the password isn't correct, the following is thrown:
org.postgresql.util.PSQLException: FATAL: password authentication failed for user "cikfedlekqbuk"
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:525) ~[postgresql-42.2.14.jar:42.2.14]
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:146) ~[postgresql-42.2.14.jar:42.2.14]
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:197) ~[postgresql-42.2.14.jar:42.2.14]
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.14.jar:42.2.14]
...
Or if the format is incorrect, this is thrown:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://url:port
... Stack trace
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://url:port
... Stack trace
Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://url:port
... Stack trace
The two possible solutions I've come across were using #ExceptionHandler or using AOP. Both failed however, because #ExceptionHandler is MVC specific and AOP wouldn't recognize the methods. Here's the example of a pointcut I've tried:
#AfterThrowing(value="execution(* org.springframework.boot.autoconfigure.orm.jpa.*())", throwing="e")
I've also tried with com.zaxxer.hikari.util.DriverDataSource and others.
Thanks in advance!

Check your application.properties:
spring.datasource.url = jdbc:postgresql://localhost:5432/database_name
spring.datasource.username = postgres
spring.datasource.password = postgres

Related

Spring boot BigQuery datasource connection

I am trying to connect BigQuery from Spring boot using Simba jdbc driver but I am getting below exception. Any input is appreciated. I am not sure why spring-boot is looking for a certifcate. I am able to connect with simple java main class, But I am getting this error with Spring boot only.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getDataSource' defined in class path resource [com/test/demo/services/config/DBConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.simba.googlebigquery.jdbc42.DataSource]: Factory method 'getDataSource' threw exception; nested exception is java.sql.SQLException: [Simba]BigQueryJDBCDriver HttpTransport IO error : PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
DataSource ds = new com.simba.googlebigquery.jdbc42.DataSource();
Connection connection = null;
ds.setURL(
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=project)id;OAuthType=0;OAuthServiceAcctEmail=serviceAccountEmail;OAuthPvtKeyPath=p12CertPath;");
ds.setProjectId("projectId");
// ds.setOAuthType(0);
// connection = ds.getConnection();
connection = ds.getConnection();
Remove the extra spaces from your JDBC URL, it looks like they are interfering with mandatory OAuthPvtKeyPath, OAuthServiceAcctEmail parameters:
jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=<Your Project ID>;OAuthType=0;OAuthServiceAcctEmail=<Your Email>;OAuthPvtKeyPath=<Path To Cert>;

Disable #SqsListener for local environment

I have the following value configured in my SQS Listener in springboot. The queue is configured only for DEV and STAGE environments. So I want to disable it in my local after testing. How do i achieve that?
#SqsListener(value = { "${cloud.aws.endpoint}" } , deletionPolicy =SqsMessageDeletionPolicy.ON_SUCCESS)
public void processMessage(String message) throws Exception {
}
I tried to add the following to my application-local.xml(to keep it local), but it didn't work. Anyone went through the same scenario?
autoconfigure:
exclude:
- org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
I am getting the following error everytime.
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 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'autoDetectingStackNameProvider' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.aws.core.env.stack.config.StackNameProvider]: Factory method 'autoDetectingStackNameProvider' threw exception; nested exception is java.lang.IllegalArgumentException: No valid instance id defined
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:799) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
com.amazonaws.SdkClientException: Failed to connect to service endpoint:
at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100) [aws-java-sdk-core-1.11.867.jar:na]
Caused by: java.net.ConnectException: Host is down (connect failed)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'autoDetectingStackNameProvider' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.aws.core.env.stack.config.StackNameProvider]: Factory method 'autoDetectingStackNameProvider' threw exception; nested exception is java.lang.IllegalArgumentException: No valid instance id defined
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.sprin
I've faced similar issues while using #SqsListener. What I usually do is comment out the annotation when running the app locally - it's ugly but it works.

Spring Unable to rollback against JDBC Connection after Postgresql process got killed

I got a problem in one of my cloud server today and it was restarted by the administrators when action was in progress. Since the restart of the server my backend doesn't want to restart, it seems like there is a problem with my postgresql database.
For information : I can connect to the database with the username and the password of the user with no problem and also do modification with pgAdmin or directly with psql.
ERROR c.b.myapp.progress.ProgressServiceImpl.updateProgressApplication (169) - error updating progress for c24f3d42-965b-459e-8afd-2e016ddb3394
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Unsatisfied dependency expressed through method 'dataSource' parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#5e57643e has not been refreshed yet
at [...]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Unsatisfied dependency expressed through method 'dataSource' parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#5e57643e has not been refreshed yet
at [...]
Caused by: org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#5e57643e has not been refreshed yet
at [...]
Caused by: java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#5e57643e has not been refreshed yet
at [...]
ERROR o.s.a.i.SimpleAsyncUncaughtExceptionHandler.handleUncaughtException (39) - Unexpected exception occurred invoking async method: public void com.myapp.progress.ProgressServiceImpl.processAllApplications()
org.springframework.orm.jpa.JpaSystemException: Unable to rollback against JDBC Connection; nested exception is org.hibernate.TransactionException: Unable to rollback against JDBC Connection
at [...]
Caused by: org.hibernate.TransactionException: Unable to rollback against JDBC Connection
at [...]
Caused by: org.postgresql.util.PSQLException: This connection has been closed.
Can someone help ? (Everything was working fine before this server restart)

Spring boot application not starting in local alone, but same code working in production and development region

I tried a lot but could not understand what is really wrong
highlights
Same code starting in development region and production without any issue
While starting in local machine am getting the following error
Basically am getting found [bigint (Types#BIGINT)], but expecting [int (Types#INTEGER)] in my error message, if I change the table field to Integer it is working fine. But the code base is really big and lot of tables involved.
Ideally, it should have started without any error messages.Kindly help me in for this
Note: Same code is was also starting in my older machines, now I got an new machine to work and along with this I got this issue also
Java jre version 1.8.0
Error
{"time":"2020-08-19T15:56:23.132+00:00","msg":"Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory","logger_name":"org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext","level":"WARN","app":"food-data-extract-service"}
{"time":"2020-08-19T15:56:23.137+00:00","msg":"Stopping service Tomcat","logger_name":"org.apache.catalina.core.StandardService","level":"INFO","app":"food-data-extract-service"}
{"time":"2020-08-19T15:56:23.147+00:00","msg":"Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available)","logger_name":"org.springframework.boot.SpringApplication","level":"WARN","app":"food-data-extract-service"}
{"time":"2020-08-19T15:56:23.156+00:00","msg":"Application startup failed","logger_name":"org.springframework.boot.SpringApplication","level":"ERROR","stack_trace":"org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)\r\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)\r\n\tat org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)\r\n\tat org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)\r\n\tat org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)\r\n\tat org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)\r\n\tat org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)\r\n\tat org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:314)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)\r\n\tat com.organisation.microservice.extract.Application.main(Application.java:18)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\r\n\tat java.lang.reflect.Method.invoke(Unknown Source)\r\n\tat org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)\r\nCaused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory\r\n\tat org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954)\r\n\tat org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882)\r\n\tat org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)\r\n\tat org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)\r\n\tat org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370)\r\n\tat org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)\r\n\t... 21 common frames omitted\r\nCaused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [id] in table [cloud_parameter_file]; found [bigint (Types#BIGINT)], but expecting [int (Types#INTEGER)]\r\n\tat org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateColumnType(SchemaValidatorImpl.java:105)\r\n\tat org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateTable(SchemaValidatorImpl.java:92)\r\n\tat org.hibernate.tool.schema.internal.SchemaValidatorImpl.doValidation(SchemaValidatorImpl.java:50)\r\n\tat org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:91)\r\n\tat org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:475)\r\n\tat org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)\r\n\tat org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)\r\n\t... 27 common frames omitted\r\n","app":"food-data-extract-service"}

Mongock and #Value annotation does not appear to work

I am trying to use the #Value annotation to grab the URI and database name while creating a SpringBootMongock object via SpringBootMongockBuilder and during mvn install it attempts to load the application context and fails because my Spring Contract tests cannot connect to the database in my application.yml file. Which I do not want while building my app anyways.
I have gotten around this by injecting the Environment object in my method signature but I don't understand why the #Value is not working. I have annotated the class with #Configuration which works fine.
Update: I still need to grab the URI from the yaml file to create my MongoClient using the #Bean annotation..
#Configuration
public class MongockConfiguration {
#Value(${spring.data.mongodb.uri})
private String uri;
#Bean
public MongoClient mongoClient(){
return MongoClients.create(uri);
}
#Bean
public SpringBootMongock mongock(Application context, Environment environment) throws Exception {
return new SpringBootMongockBuilder(mongoClient(), dbname, ChangeLogOne.class.getPackage().getName()).setEnabled(migrate).setApplicationContext(applicationContext).build();
}
some of the above values I pull from the Environment object as the #Value wasn't working for me .. no need to provide exact values here
exception is
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongock' defined in class path resource [blah/dht/mcs/registrationservice/config/MongockConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.github.cloudyrock.mongock.SpringBootMongock]: Factory method 'mongock' threw exception; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='testUser', source='admin', password=<hidden>, mechanismProperties={}}
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.github.cloudyrock.mongock.SpringBootMongock]: Factory method 'mongock' threw exception; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='testUser', source='admin', password=<hidden>, mechanismProperties={}}
Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='testUser', source='admin', password=<hidden>, mechanismProperties={}}
Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "Authentication failed.", "code" : 18, "codeName" : "AuthenticationFailed" }
and for the record with the values hardcoded vs using the #Value annotation everything works as expected.
The issue is not related to Mongock, but I see pretty clear that is due to MongoClient not being injected whenever you get the error.
As you mentioned it works when you provide the uri hardcoded, I was tempted to say that Spring doesn't find the spring.data.mongodb.uri, but if I am not wrong, it would fail saying that property is not found, rather than the error you are getting, as you are not providing a default value.
Anyway, it's something around there, for some reason, whenever you are running this and fails, the MongoClient is not added to the context for some reason.
I hope you find it useful.

Categories