스프링 부트 2.1.0 에는 스프링 5.1.0 프레임워크가 반영되었다.

스프링 5.1.0 은 컴포넌트 탐색과정에서 발생하는 오버헤드를 감소시키기 위한 여러가지 정책이 반영되었는데, 그 중에 하나가 생성한 빈을 덮어쓰는 상황을 강제적으로 제한한다.

그래서 동일한 이름을 가진 스프링 빈이 등록되려고 하면 BeanDefinitionOverrideException 이 발생한다.

DefaultListableBeanFactory 중 일부
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
    if (!isAllowBeanDefinitionOverriding()) {
        throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
    }
    else if (existingDefinition.getRole() < beanDefinition.getRole()) {
        // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
        if (logger.isInfoEnabled()) {
            logger.info("Overriding user-defined bean definition for bean '" + beanName +
                    "' with a framework-generated bean definition: replacing [" +
                    existingDefinition + "] with [" + beanDefinition + "]");
        }
    }
    else if (!beanDefinition.equals(existingDefinition)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Overriding bean definition for bean '" + beanName +
                    "' with a different definition: replacing [" + existingDefinition +
                    "] with [" + beanDefinition + "]");
        }
    }
    else {
        if (logger.isTraceEnabled()) {
            logger.trace("Overriding bean definition for bean '" + beanName +
                    "' with an equivalent definition: replacing [" + existingDefinition +
                    "] with [" + beanDefinition + "]");
        }
    }
    this.beanDefinitionMap.put(beanName, beanDefinition);
}

이는 스프링 부트의 설정이 아닌 스프링 프레임워크에서 빈을 등록하는 과정에서 발생하는 것으로 이에 대한 속성을 비활성화할 수 있는 기능을 제공한다.

spring.main.allow-bean-definition-overriding: true

위와 같이 spring.main.allow-bean-definition-overriding 속성을 true 로 선언하면 문제가 해결될 것이다. 이후에는 중복되는 빈을 찾아서 중복이 발생하지 않도록 조치해야 한다.


이미 나온지 꽤 시간이 흐른 Junit 5를 살펴보기 시작한다.


증상

Java 8을 기본으로 개발을 해오고 있다. 그러다가 외부 교육을 할 기회가 있었는데, 이 때 교육생들은 대부분 윈도우즈를 사용하고 있었고, 나와는 다르게 오라클 Java Download 환경에서 11 혹은 10 버전을 설치운영하고 있었다.

Java 10 실행환경에서 스프링 부트 프로젝트를 실행하면 Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException 가 발생한다.

JAVA 9부터 빠진 기능들이 있다.

http://openjdk.java.net/jeps/320

  • java.xml.ws (JAX-WS, plus the related technologies SAAJ and Web Services Metadata)
  • java.xml.bind (JAXB)
  • java.activation (JAF)
  • java.xml.ws.annotation (Common Annotations)
  • java.corba (CORBA)
  • java.transaction (JTA)
대충 살펴보면 XML 과 관련된 모듈이 분리됐다.



해결방법

프로젝트 의존성 내에 compile "javax.xml.bind:jaxb-api" 을 추가한다.
스프링 부트에서는 의존성 관리기능을 통해 jaxb-api 버전을 관리하고 있기 때문에 굳이 버전을 신경쓰지 않아도 된다.



지난 2018/09/20 티아카데미에서 '스프링 부트로 웹 서비스 개발하기' 라는 짧은 강연에서 사용한 발표자료 3/3 번째 발표자료


+ Recent posts