Spring looking for PostgreSql driver, but I'm using JTDS - spring-boot

Loading a spring cloud dataflow app fails with this log:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: org.postgresql.Driver
But configuration is:
spring.jpa.database=sybase
spring.datasource.url=jdbc:jtds:sybase://xxx:X000/xxxx;autoCommit=false;appName=dataflow
spring.datasource.username=xx
spring.datasource.password=xxx
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.datasource.hikari.driver-class-name=net.sourceforge.jtdatasource.jdbc.Driver
spring.datasource.hikari.pool-name=datasource-pool
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.maximum-pool-size=2
spring.datasource.hikari.minimum-idle=0
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.auto-commit=false
spring.datasource.hikari.transaction-isolation=TRANSACTION_READ_COMMITTED
Dependency:
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
PostgreSql is never specified.
Using spring boot 2.3.3
Update:
I think something in spring dataflow context is setting the driver, because it works if I create my own configuration class and don't use spring.datasource prefix:
#Configuration
public class DataSourceConfiguration {
#Bean
#Primary
#ConfigurationProperties("spring.ds")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("spring.ds.hikari")
public HikariDataSource sybaseDataSource() {
return dataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
}

Related

Start Springboot without any Undertow Configuration

I have a project which mixes 2 dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-installed-adapter</artifactId>
<version>11.0.2</version>
</dependency>
I'm getting a transitiv dependency for Undertow, which comes from
keycloak-installed-adapter
As far as I understood, Undertow is used internally within the KeyCloak libraries.
I don't want my Springboot Application to start with Undertow, nor I want that anything related with Undertow gets configured at Springboot level.
I can't find to completely exclude any Undertow configuration for Springboot. Does anyone have an idea?
Update
I now have the following:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {EmbeddedUndertow.class})
public class SpringbootTest {
public static void main(String[] args) {
SpringApplication.run(SpringbootTest.class, args);
}
}
But i'm getting following exception when starting my service:
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'undertowEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedUndertow.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory]: Factory method 'undertowEmbeddedServletContainerFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: io/undertow/servlet/api/SessionPersistenceManager
Knowing that the EmbeddedUndertow Class lokks like:
#Configuration
#ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
#ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedUndertow {
#Bean
public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
return new UndertowEmbeddedServletContainerFactory();
}
}
How would you ignore this calss from the scanning?

JedisConnectionFactory bean instantiation failure during application startup and throws java.lang.NullPointerException

I am using spring-boot-data, redis and jedis. I created jedisConnectionFactory and redisTemplate beans in a Configuration class. JedisConnectionFactory bean instantiation failure during application startup.
I use the latest libraries. This is the exception I get:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-
maven-plugin:2.2.0.BUILD-SNAPSHOT:run (default-cli) on project
Console: An exception occurred while running. null:
InvocationTargetException: Error creating bean with name
'consoleApplication': Unsatisfied dependency expressed through field
'bookRepository'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'bookRepository': Cannot resolve reference
to bean 'redisKeyValueTemplate' while setting bean property
'keyValueOperations'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'redisKeyValueTemplate': Cannot resolve
reference to bean 'redisKeyValueAdapter' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'redisKeyValueAdapter': Cannot resolve
reference to bean 'redisTemplate' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'redisTemplate' defined in class path
resource [com/console/config/AppConfig.class]: Bean instantiation
via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.springframework.data.redis.core.RedisTemplate]:
Factory method 'redisTemplate' threw exception; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jedisConnectionFactory' defined in class
path resource [com/console/config/AppConfig.class]: Bean
instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.springframework.data.redis.connection.jedis.JedisConnectionFactory]: Factory method 'jedisConnectionFactory' threw exception; nested exception is java.lang.NullPointerException -> [Help 1]
This is my pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<!-- <version>2.2.0.BUILD-SNAPSHOT</version> -->
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<!-- <version>3.0.1</version> -->
<!-- <type>jar</type> -->
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
This is my code:
#Configuration
public class AppConfig {
#Autowired
private RedisProperties redisProperties;
#Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort());redisStandaloneConfiguration.setPassword(redisProperties.getPassword());
JedisClientConfiguration.JedisClientConfigurationBuilder builder = JedisClientConfiguration.builder()
.connectTimeout(redisProperties.getTimeout())
.readTimeout(redisProperties.getJedis().getPool().getMaxWait());
if (redisProperties.isSsl())
builder.useSsl();
// Final JedisClientConfiguration
JedisClientConfiguration clientConfig = builder.build();//.usePooling().build();
return new JedisConnectionFactory(redisStandaloneConfiguration, clientConfig);
}
#Bean
public RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
JedisConnectionFactory factory = jedisConnectionFactory();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
#Repository
public interface BookRepository extends CrudRepository<Book, Long> {
}
I expect the simple application to run without exception.
Any advice and insight is appreciated.
From reviewing JedisConnectionFactory code it seem like you can get such error only if one of the arguments to the Ctor is null.
public JedisConnectionFactory(RedisStandaloneConfiguration standaloneConfig, JedisClientConfiguration clientConfig) {
this(clientConfig);
Assert.notNull(standaloneConfig, "RedisStandaloneConfiguration must not be null!");
this.standaloneConfig = standaloneConfig;
}
I had the same problem. For me, the problem was the order in which the beans were created.
It's important that the jedisConnectionFactory bean is created before any of its dependencies. A way of telling Spring about this is by using the #DependsOn annotation. You could do something like this:
#SpringBootApplication
#DependsOn("jedisConnectionFactory")
public class Application extends SpringBootServletInitializer {
...
}
There are probably better ways of solving this! My suggestion is just a workaround.

Spring throwing Circular Reference Error with ObjectMapper and RepositoryRestMvcConfiguration

I have a Spring Boot application (2.0.3) that's throwing a circular reference error involving objectMapper (faster.xml Jackson implementation, 2.9.6). It builds fine with Gradle (4.10.2), but upon deployment throws the following error:
...; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.leroyjenkins.service.common.config.CommonConfig':
Unsatisfied dependency expressed through field 'objectMappers'; nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'objectMapper' defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.fasterxml.jackson.databind.ObjectMapper]:
Circular reference involving containing bean 'org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration' -
consider declaring the factory method as static for independence from its containing instance. Factory method 'objectMapper' threw exception; nested exception is java.lang.NullPointerException",
"\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)",
The CommonConfig is referring to a configuration file I have:
#Configuration
#EnableHypermediaSupport(type = .
EnableHypermediaSupport.HypermediaType.HAL)
#EnableScheduling
#Order(Ordered.LOWEST_PRECEDENCE)
#CompileStatic
#Slf4j
#Slf4jPlusMetrics("mlog")
class CommonConfig {
...
#Autowired List<ObjectMapper> objectMappers
#PostConstruct
void afterPropertiesSet() {
log.info("initializing CommonConfig objectMappersSize={},contextPath={},threadPoolSize={},threadPoolQueueCapacity={},threadPoolDefaultTimeout={},appName={}",
objectMappers.size(), contextPath, threadPoolSize, threadPoolQueueCapacity, threadPoolDefaultTimeout, appName)
objectMappers.each { ObjectMapper objectMapper ->
objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
objectMapper.registerModule(new ParameterNamesModule())
objectMapper.registerModule(new Jdk8Module())
objectMapper.registerModule(new JavaTimeModule())
objectMapper.registerModule(new JodaModule())
objectMapper.registerModule(new GsnModelJacksonModule())
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
}
}
...
}
We just updated to jdk11...not sure if that's relevant here.

SpringBoot + Database + Elasticsearch disable JPA autoconfig

I have a springboot application which connects both to Elasticsearch and Database. Firstly I used spring-data features such as JpaRepository and ElasticsearchRepository but I would like to start using JdbcTemplate and ElasticSearchTemplate. I deleted all Jpa related services and annotations like #Entity, #Id, and created my own configuration but spring still wants to create EntityManagerFactory and use Hiberante and so on. What shall I do ?
Here is my config
#Bean(name = DE_DATABASE_BEAN_NAME)
#ConfigurationProperties(prefix = "spring.de")
#Primary
public DataSource deDBDataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = DE_DATABASE_JDBC_TEMPLATE_NAME)
public JdbcTemplate jdbcTemplate(#Qualifier(DE_DATABASE_BEAN_NAME) final DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
#Bean(name = DE_ELASTICSEARCH_TEMPLATE_NAME)
public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException {
final String server = clusterNodes.split(":")[0];
final Integer port = Integer.parseInt(clusterNodes.split(":")[1]);
final Settings settings = Settings.builder().put("cluster.name", clusterName).build();
final Client client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(server), port));
return new ElasticsearchTemplate(client);
}
And my stacktrace
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' 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.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.

MongoDB configuration in Spring Boot and Spring Data REST

I want to use MongoDB for the mongoDB with spring-boot and JPA.. I'm able to do with embedded H2 database. But I'm not sure what's going wrong using mongo-db. While running the application, I'm getting error that datasource is missing.
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages = "com..........repo")
#EnableWebMvc
#Configuration
#ComponentScan
#Import({ SpringMongoConfig.class, RepositoryRestMvcConfiguration.class })
public class Bootstrap extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
#Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(Bootstrap.class);
}
}
.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
#Configuration
#EnableMongoRepositories(basePackages = "com.............repo")
#PropertySource(value = "classpath:mongo-config.properties")
public class SpringMongoConfig extends AbstractMongoConfiguration {
#Value("${MONGO_DB_HOST}")
private String MONGO_DB_HOST;
#Value("${MONGO_DB_PORT}")
private int MONGO_DB_PORT;
#Value("${DB}")
private String DB;
#Override
protected String getDatabaseName() {
return DB;
}
#Bean
#Override
public Mongo mongo() throws Exception {
return new MongoClient(MONGO_DB_HOST, MONGO_DB_PORT);
}
}
.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
..........................
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:509)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290)
... 25 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
....................................
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
... 39 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.getDriverClassName(DataSourceProperties.java:93)
at org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource(DataSourceAutoConfiguration.java:105)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
For starters use the framework Spring Boot will do autoconfiguration for the frameworks it detects. This includes Spring Data JPA and Spring Data Mongo. So you can remove the #Enable annotation for it.
The same for Spring MVC and Spring Data Rest.
To allow Spring Boot to configure Spring Mongo add the following properties to your application.properties
spring.data.mongodb.host= # the db host
spring.data.mongodb.port=27017 # the connection port (defaults to 27107)
or the
spring.data.mongodb.uri=mongodb://localhost/test # connection URL
More on the Spring Boot Mongo support can be found in this section of the Spring Boot Reference Guide.
When not using an embedded datasource you have to specify which driver to use for this add the following property to your application.properties. This is also documented in this section of the Spring Boot Reference Guide.
spring.datasource.driverClassName=your.driver.class
I suggest moving your Bootstrap class to a top level package and remove all not needed annotations and configuration files
#EnableAutoConfiguration
#Configuration
#ComponentScan
public class Bootstrap extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Bootstrap.class);
}
}
Should be enough to bootstrap your whole application including jpa, mongo and web support.
For a quite complete list I suggest Appendix A of the Spring Boot Reference Guide.

Resources