귀신님
257
2018-11-29 11:02:02 작성 2018-11-29 11:05:17 수정됨
2
325

이클립스에서 @NotNull.List 에 대해서 java.lang.annotation.AnnotationFormatError 익셉션이 발생합니다.


안녕하세요.


아래 처럼 NotNull.List를 써서 validation 체크를 하는 부분이 있습니다.


@NotNull.List({
			@NotNull(groups = { Insert.class }, message = "이름은 필수 입력 항목입니다."),
			@NotNull(groups = { Update.class }, message = "항목이 선택되지 않았습니다.")
})
private String name;


그런데 이 소스를 intellij에서 톰캣으로 run 해보면 정상적으로 실행되는데


이클립스에서 톰캣으로 run 해보면 아래의 익셉션이 발생합니다.


java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface javax.validation.constraints.NotNull: @javax.validation.constraints.NotNull(message=항목이 선택되지 않았습니다., groups=[interface xxx.validation.group.Update], payload=[])
	at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:360)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:139)
	at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:65)
	at sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedType(TypeAnnotationParser.java:79)
	at java.lang.reflect.Field.getAnnotatedType(Field.java:1170)
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.findCascadingMetaData(AnnotationMetaDataProvider.java:614)
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.findPropertyMetaData(AnnotationMetaDataProvider.java:236)
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getFieldMetaData(AnnotationMetaDataProvider.java:225)
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.retrieveBeanConfiguration(AnnotationMetaDataProvider.java:133)
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getBeanConfiguration(AnnotationMetaDataProvider.java:124)
	at org.hibernate.validator.internal.metadata.BeanMetaDataManager.getBeanConfigurationForHierarchy(BeanMetaDataManager.java:220)
	at org.hibernate.validator.internal.metadata.BeanMetaDataManager.createBeanMetaData(BeanMetaDataManager.java:187)
	at org.hibernate.validator.internal.metadata.BeanMetaDataManager.lambda$getBeanMetaData$0(BeanMetaDataManager.java:160)
	at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324)
	at org.hibernate.validator.internal.metadata.BeanMetaDataManager.getBeanMetaData(BeanMetaDataManager.java:159)
	at org.hibernate.validator.internal.engine.ValidatorImpl.getConstraintsForClass(ValidatorImpl.java:294)
	at org.hibernate.cfg.beanvalidation.TypeSafeActivator.applyDDL(TypeSafeActivator.java:207)
	at org.hibernate.cfg.beanvalidation.TypeSafeActivator.applyRelationalConstraints(TypeSafeActivator.java:191)
	at org.hibernate.cfg.beanvalidation.TypeSafeActivator.applyRelationalConstraints(TypeSafeActivator.java:150)
	at org.hibernate.cfg.beanvalidation.TypeSafeActivator.activate(TypeSafeActivator.java:98)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:132)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:277)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:880)
	at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
	at javax.servlet.GenericServlet.init(GenericServlet.java:158)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1144)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1091)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:983)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4978)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5290)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1423)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1413)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)


어찌저찌해서 임시방편으로 jpa 속성값에 'javax.persistence.validation.mode' 를 none으로 설정하면 톰캣을 run하는데는 문제가 없는걸 발견했지만 예상하시다시피... 저 validation 이 정상적으로 동작하지 않습니다 ㅠ


<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="XXX"/>
        <property name="packagesToScan" value="XXX"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="jpaProperties">
            <props>
                ....
                <prop key="javax.persistence.validation.mode">${javax.validation.mode:auto}</prop>
            </props>
        </property>
    </bean>


IDE에 따라 이런 문제가 생길거라고는 생각치도 못했던터라, 이클립스로 생성하고 INTELLIJ로 개발하고 빌드, 배포까지 완료한 소스를 다른 분에게 넘겼는데 이런 문제가 생긴터라 난감합니다.. 소스를 수정하기엔 너무 먼길을 온거같아서 ㅠㅠ


혹시 이문제에 대해 원인이나 해결책을 아시거나, 힌트라도 있다면 답변 부탁드리겠습니다.. 감사합니다.


0
0
  • 답변 2

  • 귀신님
    257
    2018-11-29 11:18:44

    아 그리고 지금까지 테스트한 결과

    intellij에서 tomcat으로 run -> 정상동작

    intellij에서 maven으로 package후 서버에 배포 -> 정상동작

    이클립스에서 로컬 톰캣으로 run -> 구동중 에러

    이클립스에서 export해서 만든 war를 서버에 배포 -> 에러

    이클립스에서 maven으로 package 후 서버에 배포 -> 정상동작

    이클립스의 builder나..기타 다른 환경이 문제인거 같은데... 혹시 조금 더 찾아볼만한 내용이 있을까요..?

    0
  • 귀신님
    257
    2018-11-29 12:22:49

    일단 이클립스 버그라는 것 같습니다..

    https://bugs.eclipse.org/bugs/show_bug.cgi?id=533199

    https://stackoverflow.com/questions/49640244/bean-validation-duplicate-annotation-exception/49647126#49647126

    키워드를 NotNull.List로 계속 찾고 있어서 이런 글이 있는걸 몰랐네요..


    stackoverflow 글 대로 List없이 


    @NotNull(groups = { Insert.class }, message = "이름은 필수 입력 항목입니다.")
    @NotNull(groups = { Update.class }, message = "항목이 선택되지 않았습니다.")
    private String name;


    로 처리하면 인텔리j와 이클립스 모두 정상적으로 처리되는것을 확인했습니다.

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.