IT 웹개발/WEB WAS

JBoss web.xml ${...} 프로퍼티 치환 안 됨 - spec-descriptor-property-replacement

붕어,짐 2026. 7. 3. 22:31
728x90

JBoss에서 web.xml의 ${...} 변수가 치환 안 될 때 (같은 변수를 딴 데선 잘 쓰고 있었는데)

설정 파일을 환경별로 나눠야 할 일이 생겼다. 로컬/개발/운영마다 값이 달라서, 파일명에 변수를 박아 환경별로 알아서 읽게 하려고 했다.

배경

서버 JVM 옵션에 환경 구분값이 이미 넘어가고 있었다.

-Denv.name=prod   # 운영. 개발은 dev, 로컬은 local

그리고 이 변수를 스프링 설정 로딩에 이미 잘 쓰고 있었다. applicationContext_${env.name}.xml 같은 식으로. 몇 년째 멀쩡하게 돌아가는 방식이라, 이번에 새로 나누는 설정 파일도 똑같이 하면 편안하게 될 거라 생각했다.

<context-param>
    <param-name>MY_CONFIG</param-name>
    <param-value>/WEB-INF/config/config_${env.name}.properties</param-value>
</context-param>

증상

개발 Tomcat에서는 잘 됐다. 그런데 운영에 올리니까 설정 파일을 못 찾는다는 오류. 로그를 보니:

config_${env.name}.properties

치환이 안 되고 ${env.name} 문자 그대로 파일을 찾고 있었다.

헤맨 것

처음엔 파일 누락인가, 경로 오타인가 의심했다. 근데 제일 미치는 포인트는 이거였다 — 같은 변수를 쓰는 applicationContext 쪽은 운영에서도 멀쩡하게 잘 돌아가고 있었다. 변수가 안 넘어가는 거면 그쪽도 같이 죽어야 하는 거 아닌가. (변수는 무죄 같잖아)

그러다 검색해보니, 그 둘이 치환해주는 주체가 다르다더라. 스프링의 contextConfigLocation은 스프링이 알아서 플레이스홀더를 풀어주는 거고, 일반 context-param의 ${...}는 WAS가 치환해줘야 한단다. 그러니까 스프링 쪽이 잘 된다고 web.xml 전체가 치환되는 게 아니었던 것.

그리고 개발은 Tomcat, 운영은 JBoss다. Tomcat은 web.xml의 ${...}를 치환해주는데, JBoss는 이게 설정으로 꺼져 있을 수 있다더라.

원인

운영 JBoss의 standalone 설정 파일을 열어보니 진짜로 이렇게 되어 있었다.

<subsystem xmlns="urn:jboss:domain:ee:6.0">
    <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
</subsystem>

spec-descriptor-property-replacement가 false면 JBoss가 web.xml 같은 표준 descriptor 안의 ${...}를 시스템 프로퍼티로 안 바꿔준단다. JVM 옵션이 멀쩡히 넘어가고 있어도 별개라는 것.

해결

저 값을 true로 바꾸고 재기동했더니 치환이 되더라.

<spec-descriptor-property-replacement>true</spec-descriptor-property-replacement>

JBoss CLI로도 같은 걸 할 수 있다고 한다.

/subsystem=ee:write-attribute(name=spec-descriptor-property-replacement,value=true)
:reload

교훈

  • 스프링 설정에서 변수가 잘 풀린다고 web.xml의 다른 데서도 풀리는 게 아니더라 (치환 주체가 다름)
  • Tomcat에서 되는 게 JBoss에서도 된다고 보면 안 된다
  • 운영 이슈가 개발에서 재현 안 되면, 코드보다 WAS 차이부터 의심해보는 게 빠를 수도

(멀쩡히 잘 쓰던 변수라서 더 오래 헤맸다. 잘 되던 게 제일 무섭다)

 

728x90
LIST