친절한 개발자

전자정부 1.0 에서 3.0으로 업그레이드하기 본문

개발일지

전자정부 1.0 에서 3.0으로 업그레이드하기

착한 개발자 2016. 6. 9. 10:43

프로젝트중에 전자정부 1.0 초기에 개발되어서 3.0으로 업그레이드 해 달라는 이슈가 있었다.


전자정부 사이트에서 마이그레이션관련 가이드를 참고했다. 

http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:%EC%8B%A4%ED%96%89%ED%99%98%EA%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C  참고


maven 사용하고 있으므로 


<dependency>
     <groupId>egovframework.rte</groupId>
     <artifactId>egovframework.rte.psl.dataaccess</artifactId>
     <version>3.0.0</version>
</dependency>


버전을 변경했으며, pom.xml의 overview tab을 클릭하셩 Properties 를 다음과 같이 변경



Generics 적용에 따른 casting 적용을 한다.

변경 전 (예)

	public List<SynchrnServerVO> selectSynchrnServerList(SynchrnServerVO synchrnServerVO) throws Exception {
		return list("synchrnServerDAO.selectSynchrnServerList", synchrnServerVO);
	}

변경 후 (예)

	public List<SynchrnServerVO> selectSynchrnServerList(SynchrnServerVO synchrnServerVO) throws Exception {
		return (List<SynchrnServerVO>) list("synchrnServerDAO.selectSynchrnServerList", synchrnServerVO);
	}


멀티파트 관련 api 변경

변경 전 (예)

    return new MultipartParsingResult(multipartFiles, multipartParameters);

변경 후 (예)

    return new MultipartParsingResult(multipartFiles, multipartParameters, null);

대표적인 변경사항이였으며 이클립스에서 빌드에러가 없음을 확인하고 실행하였으나 다음과 같은 에러가 발생하였다.


심각: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory

   at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)

   at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)

   at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)

   at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)

   at org.springframework.web.context.ContextLoader.<clinit>(ContextLoader.java:146)

   at org.springframework.web.context.ContextLoaderListener.createContextLoader(ContextLoaderListener.java:53)

   at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:44)

   at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4236)

   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4739)

   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1061)

   at org.apache.catalina.core.StandardHost.start(StandardHost.java:822)

   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1061)

   at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)

   at org.apache.catalina.core.StandardService.start(StandardService.java:525)

   at org.apache.catalina.core.StandardServer.start(StandardServer.java:759)

   at org.apache.catalina.startup.Catalina.start(Catalina.java:595)

   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

   at java.lang.reflect.Method.invoke(Method.java:606)

   at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)

   at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)


위와 같은 에러가 발생하는 이유를 찾아 봤더니
LoggerFactory class 가 org.slf4j.impl.StaticLoggerBinder의 SINGLETON 맴버변수를 초기화하려고 시도하는데서 오는 에러이다.
즉 static 맴버변수를 외부에서 초기화하려 해서 에러가 발생했다.
static 맴버변수는 클래스가 생성될때 최초에 생성 및 초기화되어서 해당 클래스로 생성된 객체에서 
동일한 메모리 주소를 가지고 있기때문에 같은 값을 가지게 된다.
보통 객체를 heap영역에 생성되지만 static은 클래스영역에 생성된다.
따라서 클래스가 로드되어 static 맴버가 초기화된 이후에 다시 초기화 될수 없는 것이다.

그래서 slf4j의 static 맴버가 1.5.6 이상부터 private으로 접근자가 변경되었다.

slf4j의 버전을 변경한다.



마지막으로 다음과 같은 에러가 발생

Stacktrace:] with root cause

java.lang.NoSuchMethodError: org.springframework.web.bind.annotation.support.HandlerMethodResolver.<init>(Ljava/lang/Class;)


과거 여러업체를 거처온 프로젝트이다 보니 maven도 쓰면서 Web App Libraries 도 사용하고 있었던 것이다.
결국 스프링 버전이 서로다른게 각각의 경로에 있었고 특별한 라이브러리가 아닌상황(custom library)을 배제하고
전부 Web App Libraries에 있는 중복된 라이브러리를 삭제하였다.