Issue
I'm upgrading to Spring Boot 2.0.1.RELEASE, using Spring data JPA with Eclipselink as my provider and Liquibase. I'm encountering the following error trying to start the server:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/zoomdata/scheduler/service/dao/JPASpringConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.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]: Illegal arguments to factory method 'dataSource'; args: ; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:137)
at com.zoomdata.scheduler.service.Main.main(Main.java:54)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.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]: Illegal arguments to factory method 'dataSource'; args: ; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:353)
at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:385)
at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:184)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.zaxxer.hikari.HikariDataSource$$EnhancerBySpringCGLIB$$fea845fa.getConnection(<generated>)
at com.zoomdata.scheduler.service.dao.JPASpringConfiguration$1.afterPropertiesSet(JPASpringConfiguration.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1761)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1698)
... 17 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Illegal arguments to factory method 'dataSource'; args: ; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:172)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
... 32 common frames omitted
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
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)
... 33 common frames omitted
The dependencies in my POM are:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<version>2.0.0.RC1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.0.1.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>hibernate-core</artifactId>
<groupId>org.hibernate</groupId>
</exclusion>
<exclusion>
<artifactId>hibernate-entitymanager</artifactId>
<groupId>org.hibernate</groupId>
</exclusion>
<exclusion>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.0.7.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
</dependencies>
My JPA Configuration class looks like:
@Configuration
@EnableJpaRepositories("com.example.my.classes")
@EntityScan({"com.example.entities"})
public class JPASpringConfiguration extends JpaBaseConfiguration {
private String targetDatabase;
private final String sqlLoggingLevel;
@Autowired
public JPASpringConfiguration(
@Value("${spring.datasource.target-database}") String targetDatabase,
@Value("${eclipselink.logging.level.sql:INFO}") String sqlLoggingLevel,
DataSource dataSource,
JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> transactionManagerObjectProvider,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
super(dataSource, jpaProperties, transactionManagerObjectProvider, transactionManagerCustomizers);
this.targetDatabase = targetDatabase;
this.sqlLoggingLevel = sqlLoggingLevel;
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new EclipseLinkJpaVendorAdapter();
}
@Override
protected Map<String, Object> getVendorProperties() {
HashMap<String, Object> map = new HashMap<>();
map.put("eclipselink.weaving", "false");
map.put("eclipselink.target-database", targetDatabase);
map.put("eclipselink.logging.level.sql", sqlLoggingLevel);
map.put("eclipselink.cache.shared.default", "false");
map.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, IDSequenceRegistrar.class.getName());
return map;
}
@Bean
public SpringLiquibase liquibase(DataSource dataSource) {
SpringLiquibase springLiquibase = new SpringLiquibase() {
@Override
public void afterPropertiesSet() throws LiquibaseException {
configureLiquibase();
Liquibase liquibase = null;
try (Connection versionConnection = dataSource.getConnection()) {
versionConnection.setAutoCommit(true);
liquibase = createLiquibase(dataSource.getConnection());
String version = getDbVersion(versionConnection);
String previous = null;
while (!Objects.equals(version, previous)) {
setContexts(version);
performUpdate(liquibase);
previous = version;
version = getDbVersion(versionConnection);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (liquibase != null && liquibase.getDatabase() != null) {
liquibase.getDatabase().close();
}
}
}
};
springLiquibase.setDataSource(dataSource);
springLiquibase.setChangeLog("classpath:/upgrade/db-changelog.xml");
return springLiquibase;
}
private String getDbVersion(Connection connection) throws SQLException {
String sql = "select tag from databasechangelog where tag is not null order by dateexecuted desc";
try (Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(sql)) {
if (rs.next()) {
return rs.getString(1);
}
return "initial";
} catch (SQLException e) {
try (ResultSet rs = connection.getMetaData().getTables(null, null, "databasechangelog", null)) {
if (rs.next()) {
throw e;
} else {
return "initial";
}
}
}
}
private void configureLiquibase() {
ChangeFactory.getInstance().register(ChangeSetAwareCustomChangeWrapper.class);
}
}
In my application.properties, I have defined:
spring.datasource.target-database=PostgreSQL
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=myuser
spring.datasource.password=mypassword
spring.datasource.max-active=20
spring.datasource.max-idle=4
spring.datasource.max-wait=60000
spring.datasource.min-idle=2
spring.datasource.test-on-borrow=true
spring.datasource.test-on-return=true
spring.datasource.time-between-eviction-runs-millis=120000
spring.datasource.validation-query=select 1
This worked previously in Spring Boot 1.3.5 (before the HikariCP switch in Spring Boot 2). JPASpringConfiguration was formerly able to invoke super() without the additional arguments.
When I put a breakpoint in SimpleInstantiationStrategy, I can see the args passed are null.
So far I've tried:
- Using spring.datasource.hikari.* properties
- Adding @AutoConfigureAfter({ DataSourceAutoConfiguration.class }) to my configuration class
- Upgrading HikariCP to 3.2.0 from what's currently provided by Spring Boot
- Several other reworkings of various config options, properties, and classes
Thank you to anyone who can help!
Solution
I am able to use springboot with hikari. I do not see following class. Can you add and check?
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public class CustomHikariConfig extends HikariConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource(this);
}
}
Though you already mentioned that you have used spring.datasource.hikari.*, you can recheck one more time with below mentioned properties(In case if you have missed any)
###
# HikariCP Properties
###
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.maximum-pool-size=200
spring.datasource.hikari.minimum-idle=30
spring.datasource.hikari.idle-timeout=3000
spring.datasource.hikari.poolName=HikariCP
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.jdbcUrl=**data source url**
spring.datasource.hikari.username=**username**
spring.datasource.hikari.password=**password**
spring.datasource.hikari.driverClassName=com.mysql.jdbc.Driver
Answered By - Shaunak Patel
Answer Checked By - Candace Johnson (JavaFixing Volunteer)