본문 바로가기

JAVA/eGovFrame(전자정부프레임워크)

[전자정부프레임워크] java.lang.IllegalStateException: Failed to load ApplicationContext

JUnit 테스트 중 데이터베이스(DB) 연결 확인 중 발생한 에러

HikariCP를 연결하고 JUnit으로 정상적으로 연결되었는지 확인하는 코드로 아래와 같은 에러가 발생했다

 

에러 내역

더보기

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132) ~[spring-test-5.3.20.jar:5.3.20]

...

Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'dataSource' is already used in this <beans> element
Offending resource: URL [file:src/main/resources/egovframework/spring/context-datasource.xml]

at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:72) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:119) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:111) ~[spring-beans-5.3.6.jar:5.3.6]

...

Cannot convert value of type 'org.apache.commons.dbcp2.BasicDataSource' to required type 'com.zaxxer.hikari.HikariConfig': no matching editors or conversion strategy found

에러 발생 코드

DataSourceTests.java

import static org.junit.Assert.fail;

import java.sql.Connection;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import lombok.Setter;
import lombok.extern.log4j.Log4j;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/resources/egovframework/spring/context-datasource.xml")
@Log4j
public class DataSourceTests {

	@Setter(onMethod_= {@Autowired})
	private DataSource dataSource;

	@Test
	public void testConnection() {

		try (Connection con = dataSource.getConnection()){
			log.info(con);
		} catch (Exception e) {
			fail(e.getMessage());
		}
	}
}

context-datasource.xml 일부

	<context:property-placeholder location="classpath:config/database.properties" />

	<bean	id="dataSource"	class="org.apache.commons.dbcp2.BasicDataSource"	destroy-method="close">
		<property	name="driverClassName"		value="${mysql.driverClassName}"/>
		<property	name="url"			value="${mysql.url}" />
		<property	name="username"			value="${mysql.username}"/>
		<property	name="password"			value="${mysql.password}"/>
	</bean>

	<!-- HikariCP configuration -->
	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
		<constructor-arg ref="hikariConfig" />
	</bean>

경로와 import 패키지를 확인했지만 특정 어노테이션이 없어서 발생한 문제였다

 

에러 해결 코드

context-datasource.xml

	<context:property-placeholder location="classpath:config/database.properties" />

	<bean	id="hikariConfig"	class="com.zaxxer.hikari.HikariConfig">
		<property	name="driverClassName"		value="${mysql.driverClassName}"/>
		<property	name="jdbcUrl"			value="${mysql.url}" />
		<property	name="username"			value="${mysql.username}"/>
		<property	name="password"			value="${mysql.password}"/>
	</bean>

	<!-- HikariCP configuration -->
	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
		<constructor-arg ref="hikariConfig" />
	</bean>

해결

1. hikariCP(히카리씨피)에 맞게 property의 name을 url에서 jdbcurl로 변경

2. destroy-method도 제거했고

3. 빈 중에서 dataSource가 중복으로 이름이 등록되어서 DB 접속 정보 빈 이름을 변경

4. hikariCP가 참조 할 수 있도록 ref의 빈 이름을 DB 접속 정보 빈 이름과 동일하게 수정