【问题标题】:Spring boot gradle build failing due to exception "HikariPool$PoolInitializationException" in unit test由于单元测试中的异常“HikariPool$PoolInitializationException”,Spring Boot gradle 构建失败
【发布时间】:2022-02-07 10:27:05
【问题描述】:

当我们单独运行测试用例时,它们运行良好,只有在我们尝试创建构建时才会出现此异常。

这是我们为每个测试用例得到的例外。

StudentReportControllerTest > testSubmittedPaperController() FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132
        Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
            Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
                Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
        Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800

                    Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException at HikariPool.java:596
                        Caused by: org.postgresql.util.PSQLException at QueryExecutorImpl.java:2552
            Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658

                Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185

                    Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException at HikariPool.java:596

                        Caused by: org.postgresql.util.PSQLException at QueryExecutorImpl.java:2552

我们正在使用主数据库和副本数据库配置,一旦我们实施,就会发生此问题。

@Aspect
@Component
@Order(0)
public class ReadOnlyRouteInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(ReadOnlyRouteInterceptor.class);

    @Around("@annotation(transactional)")
    public Object proceed(ProceedingJoinPoint proceedingJoinPoint, Transactional transactional) throws Throwable {
        try {
            if (transactional.readOnly()) {
                RoutingDataSource.setReplicaRoute();
                logger.info("Routing database call to the read replica");
            }
            return proceedingJoinPoint.proceed();
        } finally {
            RoutingDataSource.clearReplicaRoute();
        }
    }
}
public class RoutingDataSource extends AbstractRoutingDataSource {

    private static final ThreadLocal<Route> routeContext = new ThreadLocal<>();

    public enum Route {
        PRIMARY, REPLICA
    }

    public static void clearReplicaRoute() {
        routeContext.remove();
    }

    public static void setReplicaRoute() {
        routeContext.set(Route.REPLICA);
    }

    @Override
    public Object determineCurrentLookupKey() {
        return routeContext.get();
    }
}
@Configuration
public class DataSourceConfig {

    private static final String PRIMARY_DATASOURCE_PREFIX = "spring.primary.datasource";
    private static final String REPLICA_DATASOURCE_PREFIX = "spring.replica.datasource";

    @Autowired
    private Environment environment;

    @Bean
    @Primary
    public DataSource dataSource() {
        final RoutingDataSource routingDataSource = new RoutingDataSource();

        final DataSource primaryDataSource = buildDataSource("PrimaryHikariPool", PRIMARY_DATASOURCE_PREFIX);
        final DataSource replicaDataSource = buildDataSource("ReplicaHikariPool", REPLICA_DATASOURCE_PREFIX);

        final Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(RoutingDataSource.Route.PRIMARY, primaryDataSource);
        targetDataSources.put(RoutingDataSource.Route.REPLICA, replicaDataSource);

        routingDataSource.setTargetDataSources(targetDataSources);
        routingDataSource.setDefaultTargetDataSource(primaryDataSource);

        return routingDataSource;
    }

    private DataSource buildDataSource(String poolName, String dataSourcePrefix) {
        final HikariConfig hikariConfig = new HikariConfig();

        hikariConfig.setPoolName(poolName);
        hikariConfig.setJdbcUrl(environment.getProperty(String.format("%s.url", dataSourcePrefix)));
        hikariConfig.setUsername(environment.getProperty(String.format("%s.username", dataSourcePrefix)));
        hikariConfig.setPassword(environment.getProperty(String.format("%s.password", dataSourcePrefix)));
        hikariConfig.setDriverClassName(environment.getProperty(String.format("%s.driver", dataSourcePrefix)));

        return new HikariDataSource(hikariConfig);
    }
}

我的 build.gradle

plugins {
    id 'org.springframework.boot' version '2.5.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'jacoco'
    id 'org.sonarqube' version '3.0'
}

group = 'com.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}
ext {
    set('springCloudVersion', "2020.0.2")
}
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
    implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.5.2'
    implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
    implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
    implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.6.1'
    implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis'
    implementation group: 'commons-io', name: 'commons-io', version: '2.6'
    implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')
    implementation 'com.amazonaws:aws-java-sdk-s3'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'org.postgresql:postgresql'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-config'
    implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client'
}

test {
    useJUnitPlatform()
    finalizedBy jacocoTestReport
}
jacocoTestReport {
    dependsOn test
    reports {
        //xml.required false
//      csv.enabled false
        html.enabled true
        xml.enabled false
        csv.enabled false
        html.enabled true
    }
    afterEvaluate {
        getClassDirectories().setFrom(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: [
                            '**/entity/**',
                            '**/request/**',
                            '**/dto/**',
                            '**/config/**',
                            '**/interceptor/**',
                            '**/mapper/**',
                            '**/utils/**',
                            '**/enums/**',
                            '**/response/**',
                            '**/filters/**',
                            '**/constants/**',
                            '**/exception/**',
                            '**/log/**',
                            '**/StudentTestReportApplication.class',
                    ]
            )
        })
    }
}

我的一个测试课

@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
class StudentReportControllerTest {
    @Autowired
    StudentReportController studentReportController;

    @MockBean
    PaperReportStudentService paperReportStudentService;

    @MockBean
    PaperDetailStudentService paperDetailStudentService;

    @Autowired
    TeacherReportController teacherReportController;

    @MockBean
    PaperDetailTeacherService paperDetailTeacherService;

    @MockBean
    QuestionWiseReportStudentService questionWiseReportStudentService;

    @Autowired
    private MockMvc mockMvc;

    protected String mapToJson(Object obj) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(obj);
    }

    @Test
    void getTeacherAssignmentsNegativeTest() throws Exception
        String inputJson = mapToJson(new TeacherRequest());
        final MockHttpServletResponse response =
                mockMvc
                        .perform(
                                post(REPORT_API + GET_TEACHER_ASSIGNMENTS)
                                        .content(inputJson)
                                        .contentType(MediaType.APPLICATION_JSON)
                                        .accept(MediaType.APPLICATION_JSON))
                        .andReturn()
                        .getResponse();

        assertThat(new JSONObject(response.getContentAsString()).get("status")).isEqualTo(404);
        assertThat(new JSONObject(response.getContentAsString()).get("message")).isEqualTo(Constants.RECORD_NOT_FOUND);
    }

这是我们的属性文件

spring.cloud.config.import-check.enabled=false
spring.jpa.show-sql=true
spring.datasource.initialization-mode=always
spring.datasource.initialize=true
spring.datasource.continue-on-error=true
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.minimum-idle=1
spring.datasource.hikari.maximum-pool-size=1
spring.redis.timeout=2000
spring.jackson.property-naming-strategy=SNAKE_CASE
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Asia/Kolkata
spring.data.redis.timeout=3000
eureka.client.enabled=false
#
spring.primary.datasource.password=postgres
spring.primary.datasource.username=postgres
spring.primary.datasource.driver=org.postgresql.Driver
spring.primary.datasource.url=jdbc:postgresql://127.0.0.1/master?stringtype=unspecified
#
spring.replica.datasource.password=postgres
spring.replica.datasource.username=postgres
spring.replica.datasource.driver=org.postgresql.Driver
spring.replica.datasource.url=jdbc:postgresql://127.0.0.1/replica?stringtype=unspecified

【问题讨论】:

  • 我现在已经解决了这个问题。为了获得更好的异常细节,我尝试了“Gradle check”,然后我发现这个问题是由于我们的数据库上的连接大小有限,我们在单元测试中不知不觉地创建了数据库连接。

标签: java spring-boot gradle build hikaricp


【解决方案1】:

我现在已经解决了这个问题。为了获得更好的异常细节,我尝试了“Gradle check”,然后我发现这个问题是由于我们的数据库上的连接大小有限,我们在单元测试中不知不觉地创建了数据库连接。

【讨论】:

    猜你喜欢
    • 2013-02-26
    • 2022-06-14
    • 1970-01-01
    • 2017-02-21
    • 2020-12-22
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    相关资源
    最近更新 更多