본문 바로가기
카테고리 없음

JEUS 에러 ( marshalling the XML descriptor failed )

by techdebt 2025. 1. 13.
반응형

JEUS이슈

JEUS 문제 상황

JEUS에서 발생한 오류로서, Spring Boot 3.2.2로 개발된 애플리케이션을 JEUS 8.5 환경에 배포하려 했습니다. springboot를 사용하지만 JEUS에 배포를 했어야 하므로, 일반적으로 boot와 함께 사용되는 Tomcat을 제외하고 직접 배포를 시도했는데, 이 과정에서 예상치 못한 에러가 발생했습니다. 특히 배포 과정 중 web-fragment.xml 파일을 처리하는 단계에서 문제가 발생했는데, 이는 단순한 구성 오류를 넘어서는 근본적인 호환성 문제였습니다.

JEUS 에러 내용 

[2025.01.12 23:10:01:959][0] [server1-27] [SERVER-0522] An exception occurred while processing [/home/jeus/jeus8_5/domains/jeus_domain_002/servers/server1/.workspace/deployed/test001/backend-sample001-0_0_1-SNAPSHOT-plain_war___/WEB-INF/lib/spring-web-6.2.1.jar/META-INF/web-fragment.xml].
<<__Exception__>>
jeus.xml.binding.JeusJAXBException: Unmarshalling the XML descriptor failed: META-INF/web-fragment.xml
class org.xml.sax.SAXParseException :
cvc-elt.1.a: Cannot find the declaration of element 'web-fragment'..
        at jeus.xml.binding.BindingHelper.getDescriptor(BindingHelper.java:77)
        at jeus.xml.binding.BindingHelper.getDescriptor(BindingHelper.java:43)
        at jeus.service.descriptor.DescriptorFile.getDeploymentDescriptor(DescriptorFile.java:129)
        at jeus.servlet.deployment.ConfigUtil.readWebFragmentDescriptor(ConfigUtil.java:135)
        at jeus.servlet.deployment.ConfigUtil.readWebFragmentDescriptor(ConfigUtil.java:129)
        at jeus.servlet.engine.Context.readWebFragments(Context.java:1146)
        at jeus.servlet.engine.Context.init0(Context.java:813)
        at jeus.servlet.engine.Context.init(Context.java:651)
        at jeus.servlet.engine.VirtualHost.deployContext(VirtualHost.java:121)
        at jeus.servlet.common.WebContainerManager.createAndAddContext(WebContainerManager.java:843)
        at jeus.servlet.common.WebContainerManager.deployContext(WebContainerManager.java:818)
        at jeus.servlet.deployment.WebModuleDeployer.distribute1(WebModuleDeployer.java:142)
        at jeus.deploy.deployer.AbstractDeployer.distribute(AbstractDeployer.java:243)
        at jeus.deploy.deployer.DeploymentAdministrator.distribute(DeploymentAdministrator.java:244)
        at jeus.deploy.deployer.DeploymentAdministrator.distribute(DeploymentAdministrator.java:177)
        at jeus.server.service.internal.ServerDeploymentService.distribute(ServerDeploymentService.java:166)
        at jeus.server.service.internal.ServerDeploymentService.distribute(ServerDeploymentService.java:203)
        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 sun.reflect.misc.Trampoline.invoke(MethodUtil.java:72)
        at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:276)
        at cohttp://m.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112)
        at cohttp://m.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46)
        at cohttp://m.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237)
        at cohttp://m.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138)
        at cohttp://m.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252)
        at cohttp://m.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at cohttp://m.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at jeus.management.JeusMBeanServerAccessController.invoke(JeusMBeanServerAccessController.java:576)
        at javax.management.remote.generic.ServerIntermediary.handleRequest(ServerIntermediary.java:270)
        at javax.management.remote.generic.ServerIntermediary$PrivilegedRequestJob.run(ServerIntermediary.java:941)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.management.remote.generic.ServerIntermediary$RequestHandler.handleMBSReqMessage(ServerIntermediary.java:717)
        at javax.management.remote.generic.ServerIntermediary$RequestHandler.execute(ServerIntermediary.java:619)

 

JEUS 에러 원인

cvc-elt.1.a: Cannot find the declaration of element 'web-fragment'

이 에러 메시지는 XML 스키마 검증 과정에서 발생했으며, JEUS가 web-fragment 요소의 선언을 찾지 못했다는 것을 나타냅니다. 스택 트레이스를 자세히 분석해보면, 이 문제가 JEUS의 XML 파서에서 시작되어 전체 배포 프로세스에 영향을 미치는 것을 알 수 있습니다.

이 에러는 단순한 구성 오류가 아닌 두 기술 스택 간의 근본적인 호환성 문제를 언급하는 에러입니다. 문제의 핵심은 JAVA EE에서 Jakarta EE로의 전환에 있습니다. Spring Boot 3.x (Spring Framework 6.x)와 JEUS 8.5 서버 간의 호환성 문제로 발생한 에러입니다. Spring Boot 3.x는 Jakarta EE 9+ 스펙을 사용하는데, JEUS 8.5는 이전 버전의 Java EE 스펙을 사용하기 때문입니다.

좀 더 자세히 살펴보면,

  • 스펙 버전의 진화
    • Spring Boot 3.x는 최신 Jakarta EE 9+ 스펙을 채택했습니다. 이는 현대적인 클라우드 네이티브 애플리케이션 개발을 지원하기 위한 중요한 진보입니다.
    • 반면 JEUS 8.5는 여전히 전통적인 Java EE 스펙을 기반으로 합니다. 이는 많은 엔터프라이즈 시스템의 현실을 반영합니다.
  • 패키지 네임스페이스의 변경
    • Jakarta EE로의 전환 과정에서 가장 눈에 띄는 변화는 패키지 네임스페이스의 변경입니다.
    • 기존의 javax.* 패키지들이 jakarta.* 로 변경되었습니다.
    • 이는 단순한 이름 변경이 아닌, Oracle로부터의 자바 엔터프라이즈 플랫폼의 독립을 상징하는 중요한 변화입니다.

이러한 차이는 특히 web-fragment.xml과 같은 배포 디스크립터 처리 과정에서 명확하게 드러납니다. JEUS 8.5의 XML 파서는 Jakarta EE 9+의 새로운 스키마를 인식하지 못하여 파싱에 실패하게 됩니다.

JEUS 에러 해결 방법

이 문제를 해결하기 위한 접근 방법은 크게 세 가지가 있습니다. 

  • Spring Boot 버전 다운그레이드
    Spring Boot 2.7.x 버전을 사용하면 Java EE 스펙을 따르므로 JEUS 8.5와 호환됩니다.
# MAVEN
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
</parent>

 

 

  • JEUS 버전 업그레이드
    JEUS의 새로운 버전을 요청할 수 있겠지만, 저희 회사 담당 TMAX엔지니어를 통해서 확인한 결과는 아직 그 이상 버전이 나오지 않은 것으로 알고 있습니다. 향후에는 지원이 될 것으로 예상 됩니다. 

  • 호환성 레이어 도입
    Spring Boot 3.x 애플리케이션을 Java EE 호환 방식으로 패키징하는 변환 도구나 미들웨어를 사용할 수 있습니다.

 

현실적인 권장 사항

현재 상황에서는 다음과 같은 단계별 접근을 권장합니다:

 

단기 해결책:

Spring Boot 2.7.x 버전을 사용하여 시스템의 안정성을 우선 확보합니다. 이는 현재 프로덕션 환경에서 가장 안전한 선택입니다.

 

중기 계획

JEUS의 Jakarta EE 지원 로드맵을 지속적으로 모니터링합니다.

개발팀과 운영팀 간의 긴밀한 협력을 통해 버전 업그레이드 계획을 수립합니다.

테스트 환경에서 다양한 버전 조합을 검증합니다.

 

장기 전략

JEUS를 사용하지 않는 클라우드 네이티브 아키텍처로의 점진적 전환을 고려합니다.
다만 장기전략의 경우 회사에 규모, 일일 트래픽, 시스템의 중요도 등 다양하게 고려할 사항이 많으니 

기간을 두고 검토 및 설계를 꾸준하게 진행 합니다.

결론

엔터프라이즈 환경에서 최신 프레임워크와 레거시 인프라 간의 균형을 맞추는 것은 굉장히 중요합니다. 특히 Java 생태계가 Jakarta EE로 전환하는 과도기에 있는 현재, 이러한 호환성 문제는 더욱 빈번하게 발생할 수 있습니다. 따라서 신중한 버전 선택과 충분한 테스트가 필수적입니다. 추천하는 방법은 회사 내에 인프라에 F/W 개발 플랫폼 버전을 맞추되, 신 기술 도입을 지속적으로 검토하는 것이 좋을 듯합니다.