오류 해결/환경

[WAS] JEUS 에서 Tomcat 으로 전환하기 (Intellij Tomcat 연동)

Kyle H 2023. 1. 20. 02:30

회사에서 로컬 WAS 환경을 JEUS6.0에서 Tomcat6 버전으로 바꾸면서 겪은 것들을 기록해보려 합니다.

이와 같은 일을 할 사람이 많이 없을 것 같지만, 자리 이동시를 대비하고, 대단하진 않지만 그 과정에서 얻는 내용을 적어보겠습니다.

망분리가 이뤄지는 환경이라 스크린샷은 개인 PC 환경으로 조금씩 대체해보겠습니다.

 

1. 상황

  그간은 회사에서 10년도 넘은 시스템을 개발/운영 하였습니다. 개발 환경은 Java 7, JEUS6.0 (WAS), WebtoB (WEB), Xplatform (프론트 툴), Svn (형상관리) 등.. 금융사에서 많이 사용하는 업체 제품과, IDE는 Ecplise만 지원받았습니다. 그러다 회사 젊은층을 중심으로 JetBrains 제품을 사달라는 얘기가 나왔고, Java 환경을 사용하던 저는 Intellij를 지원받습니다.

 

  기존의 사용하던 Ecplise도 완전 과거버전에서만 호환이 되었기 때문에.. 상당히 불만이 많았었고 (망분리라 플러그인도 다운 받기 어려움), Intellij를 개인적으로는 계속 써왔기 때문에, 신규 개발 시스템들은 모두 Intellij 환경으로 설정하게 됩니다.

2. 문제 

  신규 시스템들의 환경 설정은 크게 어려울 것이 없었는데, JEUS6.0을 사용하던 주 운영 시스템이 문제가 되었습니다.

Tomcat 뿐이다.

  네 WAS 서버에 배포를 해야하는데, JEUS가, 그것도 6.0 버전은 Intellij에서 지원하는게 말이 안됐습니다. 기존에 사용하던 Ecplise 에선 티맥스 쪽에서 플러그인을 지원했던 것 같습니다. 이전에는 로컬에 WebtoB로 WEB 환경도 설정 되어 있었지만, 로컬에선 굳이 아파치까지 설정할 필요는 없었기에 Tomcat 만 새로 셋팅하면 되겠지 생각합니다. 

참고로 운영 환경에서도 Tomcat은 사용하지 않습니다. 
중앙에서 WAS(JEUS)를 운용하고 각각 class들을 배포하는 형식입니다.
개발환경에서 JEUS를 까본적이 있는데 Tomcat과 크게 차이는 없었습니다.

3. 처리

3-1. Tomcat 서버 추가 후 셋팅

  먼저 Tomcat을 설치해야 합니다.

Tomcat은 엄밀히 말하면 WAS라기 보다 서블릿 컨테이너입니다. Servlet Spec과 JSP Spec이 지원되어야 하고, Java Version도 지원가능한지 확인합니다. 저는 회사 환경에선 Tomcat 6.0.53 버전을 archived 페이지에서 따로 다운 받았고, 개인 PC 환경에선 10.1.5 버전을 다운 받아보겠습니다.

Which Version

개인 PC(Mac) 환경에선 10.1.5 버전을 설치해 보겠습니다.

Core / zip을 누르면 바로 다운로드 됩니다. 용량은 16MB 정도입니다.

Tomcat을 설치했으면 Intellij에 셋팅해줍니다. 다운 받은 폴더 그대로를 Tomcat 홈으로 설정합니다.

실행에서 구성 편집을 들어갑니다. 오른쪽 상단의 빌드 모양 오른쪽 드롭박스에서 바로 들어가도 됩니다.

왼쪽 상단 + 를 눌러 Tomcat local을 추가해줍니다. VM 옵션에 인코딩 형식을 UTF-8로 명시해 줬습니다.

현재 개인 PC에선 Zulu11을 사용하지만, 회사 PC에선 레거시 환경에 대해선 Zulu7을 사용합니다. default는 Zulu8로 되어있기 때문에 저 부분을 변경해줍니다.

배포 형식은 exploded를 사용했습니다. War를 사용하면 프로그램 수정 시 다시 .war 파일을 만들어야 합니다. exploded는 타겟 폴더에 업데이트된 항목에 대해서 copy를 진행합니다. 

그리고 애플리케이션 컨텍스트는 /로 바꾸어 줍니다. 저 부분이 모듈명으로 되어있을 시 기본 경로가 

"localhost:8080/모듈명" 이 되어버립니다. 편의성을 위해 /로 바꾸어줍니다.

처음으로 애먹은 부분입니다. 

 

설정을 완료하고 저 오른쪽 실행 버튼을 누르면 설정한 Tomcat 홈 디렉토리에 있는 /bin/catalina.sh 파일이 호출됩니다. 

저 쉘 파일에 대해 별도의 설정을 해주지 않고 실행을 했더니 

JAVA_HOME should point to a JDK not a JRE

위 에러를 만나게 됩니다.


3-2. Tomcat 설정 변경

저의 회사 PC는 JAVA_HOME 이 Zulu8의 JDK 경로로 이미 설정되어 있었습니다. 그런데 실행하고자 하는 JDK 환경은 Zulu7입니다. 

검색을 해보니 저 쉘 경로에 JAVA_HOME을 지정하면 된다고 합니다. (윈도우에선 catalina.bat을 사용합니다.)

set JAVA_HOME으로 JDK의 절대경로를 지정해줍니다.

필요한 클래스패스의 경우도 아래와 같이 지정해줍니다.

set JAVA_HOME=C:\Zulu\zulu7
...
rem 추가로 원하는 클래스 패스 지정
set CLASSPATH=원하는경로1;원하는경로;

그리고 conf/context.xml을 열어보면 다음처럼 되어있습니다.

해당 파일을 복사하여 프로젝트의 META-INF 폴더에 넣어주었습니다.

{Tomcat_HOME}/conf/context.xml 파일을 고치게 되면 해당 tomcat을 사용하는 모든 애플리케이션에 영향을 주고, META-INF에 복사하여 변경해주면 해당 애플리케이션에서만 사용할 수 있습니다. 저는 여기에 JNDI 설정해놓은 것이 있어서 복사하여 사용하였습니다.

<Context ...>
  ...
  <Resource name="jdbc/EmployeeDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="dbusername"
            password="dbpassword"
            driverClassName="org.hsql.jdbcDriver"
            url="jdbc:HypersonicSQL:database"
            maxTotal="8"
            maxIdle="4"/>
  ...
</Context>

(Tomcat 공식 홈페이지에서 가져온 예시 코드입니다.)

JNDI : Java Naming and Directory Interface
JNDI에 관한 내용은 따로 포스팅으로 정리해보겠습니다.

주의할 점은 Tomcat 버전별로 JNDI에서 사용하는 factory의 이름과 위치가 다르다는 점입니다. Tomcat 6의 경우에는 

org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory

의 기본 위치를 갖고 있습니다. 이 부분이 다르게 명시되어 있으면 변경해줍니다.

 


3-3. 프로젝트 구조 설정

아래 캡쳐는 회사 환경이 아닌 개인 PC 환경이라 다르다는 점 참고 부탁드립니다.

Mac에선 Cmd + ; 

Windows에선 Ctrl + Alt + Shift + S 를 눌러 프로젝트 설정으로 들어갑니다.

일단 SDK와 언어수준을 원하는 수준으로 맞추어 줍니다. 저는 회사 환경에선 Zulu7에 맞추어 주었습니다.

모듈에서 소스와 리소스 폴더, 제외 폴더를 잡아줍니다. 

라이브러리에서는 프로젝트 내부 lib 폴더를 클래스로만 추가해 주었습니다. 저의 경우 모드 .jar 파일로 되어있습니다.

회사에선 Web 아래 exploded 하나만 잡혔고, 그곳에 web.xml이 있어서 보였습니다. 현재 프로젝트에는 web.xml 이 없어서 보이지 않는데, 중요한 것은 좀 전에 META-INF/context.xml 을 복사했다면 이곳에 나와야 합니다. 없다면 애플리케이션 및 서버별 설명자를 추가하여 context.xml을 추가해주고 위의 설정을 해줍니다.

아티팩트 출력 루트 설정입니다. war Exploded로 배포하면 WEB-INF 아래로 배포가 됩니다. 저의 회사 환경에선 WEB-INF 아래에 lib 폴더가 있어서 괜찮았는데, 만약 다른곳에 있었다면 오른쪽에 사용 가능한 요소를 옮겨서 복사를 해줬어야 할거 같네요.


4. 오류 해결 - 메서드 중복

이제 실행버튼을 통해 실행하면 Tomcat이 실행됩니다.

문제 없이 잘 돌아가면 좋았겠지만..

java.lang.AbstractMethodError: org.apache.crimson.tree.XmlDocument.getXmlEncoding()Ljava/lang/String;
	at com.sz.service.sqlmap.XMLFileSqlapFactoryService.createSqlMapRecord(Unknown Source)
	at com.sz.service.sqlmap.XMLFileSqlapFactoryService.createSqlMapRecord(Unknown Source)
	at com.sz.service.sqlmap.MMLFileSqlapFactoryService.access$300(Unknown Source)
	at com.sz.service.sqlmap.XMLFileSqlapFactoryService$FileParser.consume(Unknown Source)
	at con.sz.util.daemon.Daemon.run (Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

하필 Daemon으로 뜨는 서비스 중 하나에서 AbstractMethodError 가 발생합니다. Exception이 터지면 일단 로컬에서 Tomcat을 띄어도 화면에서 계속해서 에러 메시지가 뜨게 됩니다.. 아무리 WAS에서 요청을 받고 넘기는 동작 과정을 생각해도 JEUS에서 Tomcat으로 변경해도 문제 없을 것 같은데, 왜 이런 오류가 발생하는지 처음엔 도무지 이해할 수 없었습니다.

 

결론적으로 문제는 메서드의 중복 이었습니다.

 

AbstractMethodError의 발생 원인을 검색해보니, 종속성을 고려하지 않고 인터페이스만 업데이트하고 구현 클래스는 업데이트하지 않은 경우나, 메서드가 중복되어 어느 메서드를 참고해야할지 모를때, 런타임에 발생할 수 있다고 합니다.

 

Intellij는 디컴파일러 덕분에 jar 파일 내부를 볼 수 있습니다. 에러 발생 부분들을 따라가다 보니 팩토리 메서드 쪽이 의심이 됩니다. 해당 메서드의 구현 클래스를 확인해보니(Cmd + Opt + B / Ctrl + Alt + B) 저 위의 crimson 패키지와 zulu7의 내부 패키지가 나옵니다. 로컬 환경이기 때문에 과감히 crimson 패키지를 삭제해 버립니다. 그리고 다시 실행...

 

JEUS에 관해 이것저것 검색을 해보다가 알게 된 내용 중 하나가 떠올랐는데, JEUS는 라이브러리의 중복을 자체적으로 적절히 처리할 수 있다는 내용이었습니다. 그래서 안정화된 버전은 꽤 잘만든 툴이라고 한 글이 생각났습니다. JEUS에선 그래서 오류가 발생하지 않았던 거 같습니다.

5. 실행

처음에 설정한 구성으로 Tomcat을 선택하고 실행 버튼을 누릅니다.

조회버튼으로 db에서 데이터도 불러봅니다. 

잘 실행되고 로그도 정상적으로 출력됩니다!

 

개인 PC에서도 간단히 확인해보겠습니다.

기본적으로 localhost:8080/으로 생성된 요청은 Tomcat의 /conf/web.xml 에서 한번 걸리지고, 설정된 welcome 페이지가 호출됩니다.

저의 경우 src/main/webapp/index.html 이 호출됩니다.

 

아까 설정한 자바 홈도 잘 나옵니다.

 

다소 부족한 부분이 있을 수 있습니다! 끝!