Reputation: 31252
Here is the DbConfig of my spring-boot application.
@Configuration
@EnableTransactionManagement
public class DBConfig
{
@Bean
public LocalSessionFactoryBean sessionFactory()
{
....
}
@Bean
public DataSource aaDataSource()
{
.....
}
public PlatformTransactionManager transactionManager()
{
....
}
private Properties hibernateProperties()
{
....
}
}
Here is my test class
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ApplicationTests {
@Test
public void contextLoads() {
}
}
Its a gradle project.
when I run gradlew clean build
locally, I get successful build since my connection settings in application.properties matches my sql connection.
But when I run from jenkins box in our qa environment (the database is qa one), the build fails with following exception.
java.lang.IllegalStateException: Failed to load ApplicationContext
....
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.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 com.zaxxer.hikari.pool.PoolInitializationException: Exception during pool initialization
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(Abstract
.....
Caused by: com.zaxxer.hikari.pool.PoolInitializationException: Exception during pool initialization
at com.zaxxer.hikari.pool.BaseHikariPool.initializeConnections(BaseHikariPool.java:544)
at com.zaxxer.hikari.pool.BaseHikariPool.<init>(BaseHikariPool.java:171)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:60)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:48)
.....
Caused by: java.sql.SQLException: Access denied for user 'admin1'@'localhost' (using password: YES)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3835)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3771)
I tried running gradlew clean build -Dspring.profiles.active=qa
with application-qa.properties in the src/main/resources/ that have qa db settings. The build still failed with same exception.
I have two options.
run the build skipping datasource bean creation. I still need my units tests to be run since they don't rely on datasource
or pass the right settings to gradle build so that application context is created.
I prefer second option to get it working
Upvotes: 2
Views: 11411
Reputation: 31207
If your requirement is that you control this externally (i.e., via the command line when launching Gradle), you can then modify your Gradle test
task configuration as follows.
test {
systemProperty("spring.profiles.active", project.properties.get("springProfiles"))
// ...
}
And then you can set a value for springProfiles
like this: gradlew clean build -PspringProfiles=ci
(where ci
is the name of the profile you want active on the CI server).
The above will make spring.profiles.active
available as a JVM system property for your tests; however, you'd still need to set the active profiles for the Spring TestContext Framework.
To do that, you need to annotate your test class with @ActiveProfiles
, but instead of passing in static profiles you'd need to implement a custom ActiveProfilesResolver
and register it via @ActiveProfiles(resolver = MyCustomResolver.class)
. Your customer resolver could then read then simply return the value of the spring.profiles.active
system property.
Another option is to implement a custom ApplicationContextInitializer
that programmatically sets the active profiles (similar to the custom ActiveProfilesResolver
). You can configure one of those via @SpringApplicationConfiguration(initializers = MyCustomInitializer.class)
.
And yet another option would be to programmatically set the active profiles directly in your SpringApplication
-- for example, based on a system property or environment variable.
So, you have several options.
Upvotes: 7