'KG 유지보수'에 해당되는 글 13

  1. 2011.07.28 JEUS에서 WEB-INF/lib/에 있는 jar를 인식하지 못함.
  2. 2011.06.26 [TroubleShooting] 특정 업체의 데이터만 이상한 경우
  3. 2011.06.02 Tried all: '1' addresses, but could not connect over HTTP to server: 'localhost', port: '80'
  4. 2011.06.01 JEUS 에서 어플리케이션을 인식하지 못하고 404 에러가 발생함.
  5. 2011.04.26 교만함
  6. 2011.03.30 인증서를 사용해서 전자서명, 암/복호화를 하는 통신 모듈을 테스트하기
  7. 2010.11.11 왜 소스를 보지 못하나.
  8. 2010.10.22 외부 시스템과의 연동 테스트시 로컬에서 진행하기???
  9. 2010.08.27 Tomcat 표준출력을 파일로 남기기
  10. 2010.07.14 Mapping of MIME Types
  11. 2009.08.04 javap로 클래스 파일 버전 확인
  12. 2009.06.18 ORA-01461: LONG 값은 LONG 열에만 입력할 수 있습니다
  13. 2008.12.26 시스템 정보 조회용 JSP

JEUS에서 WEB-INF/lib/에 있는 jar를 인식하지 못함.

java.lang.NoClassDefFoundError: org/springframework/core/ErrorCoded

JEUS에서 WEB-INF/lib/에 있는 jar를 인식하지 못함.
끙...
JEUS의 해당 컨테이너를 내렸다 올려도 해결되지 않음.
Unix라서 권한 관련 문제일수도 있겠다고 생각했는데 이 컨테이너만 이런 문제가 발생.

컨테이너 재시작 명령어가 rbcon 3 이라는 말을 듣고 확인해봄.

> which rbcon
/app/util/rbcon

> cat /app/util/rbcon
host=`uname -n`
NodeName=${host}_container$1
echo "NodeName : " ${NodeName}
if [[ $# -eq 0 ]]; then
        echo "usage : rbcon CONTAINER_NUMBER"
        return;
fi;
echo "------------------------"
echo "| Container Restarting |"
echo "------------------------"

jeusadmin ${host} -Uadministrator -P1234 downcon ${NodeName}
jeusadmin ${host} -Uadministrator -P1234 startcon ${NodeName}


컨테이너 이름이 3으로 끝난다.

/app/tmax/jeus5/config/PROD10/JEUSMain.xml을 확인해 본다. 컨테이너 3이 아니라 4다.
담당자가 잘못 알려준거다.
해당 컨테이너를 내렸다 올리니 제대로 구동됨.

혹시나 하고 의심했던 부분이 역시나 였다.
WAS 기술지원하는 회사에 바로 전화했으면 바보될뻔 했다.

[TroubleShooting] 특정 업체의 데이터만 이상한 경우

XML 로 데이터를 주고 받는데 특정 업체의 데이터만 뷰어에 나타나지 않는다.
로그에는 별다른 에러도 없고.

전달된 XML 을 살펴봐도 다른 업체 XML 과 다른 것이 없음.
내부 시스템의 소스를 볼 수가 없는 상황에서 해결이 되지 않고 있음.

내부 시스템 담당자와 디버깅을 하다 보니 URL 에 공백이 보인다.
WebSquare 를 사용하고 있었는데 에러가 명확하게 나오지 않아 힘들었는데 우연찮게 이것을 발견하였다.
이 URL 을 확인해보니 각 업체의 등록정보에서 가져오는데 특정 업체의 URL 에 공백이 포함되어 있었다.

처음부터 이렇게 접근했으면...

- 다른 업체 데이터는 문제가 없는데 이 업체 데이터가 문제가 발생한다.
전체 프로그램에는 이상이 없다.

- 그럼 다른 업체와 차이점은?
업체 등록은 각 업체의 정보를 입력한다. 이 부분이 다르다.

Tried all: '1' addresses, but could not connect over HTTP to server: 'localhost', port: '80'

URLConnection 을 이용해서 요청을 처리하는 프로그램에서 발생
WAS 는 WebLogic 10

주소를 잘못 입력한 경우
또는
접속하려는 서버가 내려가 있는 경우

JEUS 에서 어플리케이션을 인식하지 못하고 404 에러가 발생함.

KGModule 을 업그레이드함.
JEUS 를 재기동하고 어플리케이션을 호출해 보니 404 에러가 발생함.

root 사용자로 파일을 올려서 권한이 없어서 404 에러가 남.
jeus-web-dd.xml 이 파일만 생기고 내용이 없음.

권한을 바꿔줌.
chown -R jeus KGModule/

교만함

너무 부주의하다.
개발기에서 실수하고는 운영기에서 똑같은 실수를 한다.
진심으로 반성하지 않고 변명으로 순간만 모면하고자 했던거 같다.

사람이 교만하구나.

인증서를 사용해서 전자서명, 암/복호화를 하는 통신 모듈을 테스트하기

- 서버 to 서버 통신을 하는 모듈
- SendSOAPServlet -> SendSOAPServiceImpl -> SOAPMessage 를 사용하는 구조임.

- SendSOAPServiceImpl#proc(...) 를 수정하고자 함.
이 메서드는
  1. 데이터를 가져와서
  2. XML 문서를 생성하고
  3. SOAPEnvelope 와 SOAPMessage 를 생성하고
  4. 생성된 XML 문서를 MIME 에 추가한다.
  5. 첨부파일을 암호화해서 추가
  6. 전자서명 생성, 검증
  7. MimeBodyPart 생성
  8. XML, SOAP 파일로 저장
  9. 전송
  10. 응답 수신
을 처리한다.

1) 서버에 접속하지 못하므로 전송시 에러가 무조건 발생함.
이 예외를 처리하고 SOAP 메세지에서 MessageDigest, SignatureValue 를 비교해 보면 됨.

2) 굳이 통신까지 가지 않아도 전송 전 SOAP 메세지가 제대로 만들어졌는지만 확인하면 됨.
(proc 메서드가 나누어졌으면 테스트 하기 쉬웠을텐데 덩치가 너무 크다.)
SOAPMessage 클래스를 테스트하면 된다.

- 관련 파일이 많아서 해당 패키지 아래에 res/ 를 만들었다.
(여기에 각 인증서 디렉토리, 로그 디렉토리 등을 둔다.)

- XML 문서는 미리 만들어진 파일을 이용함.(데이터베이스 연결이 필요없음)

- 설정파일에서 읽어오는 부분을 직접 하드코딩함.
(이 부분이 변경되는 것도 아니고, 별도의 테스트용 설정 파일을 만들 필요가 없었다. - 이 부분은 상황마다 다르겠지.)

- 테스트를 위한 인증관련 설정파일을 별도로 만들어서 res/ 에 두었다.
이렇게 테스트하니 인증관련 설정파일에 대한 설정을 이것저것 바꿔가면서 계속 실행해 볼 수 있어 각 설정값의 역할에 대해서 깊게 이해할 수 있었다.

- 인증서 암호파일은 각 머신에서 생성되어야 하므로 테스트 전 직접 생성해야 한다.

- 기존에 문제없이 돌아가던 모듈이므로 먼저 이에 대한 테스트 코드를 작성한다.
그리고 원하는 기능에 대한 테스트  코드를 추가한다.

왜 소스를 보지 못하나.

SOAP을 통해서 데이터를 주고 받는 시스템
데이터가 조금 많기는 하지만 내부 업무 로직이 더 복잡하다.
금액을 계산하고 과거 데이터를 조회하고.
나는 서버측과 클라이언트측 중간에서 데이터를 전달하는 모듈을 맡고 있다.

이 시스템을 유지보수하는 인력들의 기술력은 그다지 높지 않다.
업무를 잘 알기는 하지만 자바 기초 문법 정도만 알고 있다.

이런 상황에서 서버측 문제가 발생하면 해결을 하지 못한다.
담당자들이 소스를 아무리 들여다보고 있어도 추측만 할 뿐이지 명확하게 이야기하지 못한다.
SOAP 메세지를 파싱하고 복호화를 해서 데이터(XML)를 가져와서 내부 업무 로직을 태우는데 자바에 익숙지 않아서 무리가 따른다.

덩치 큰 업무 시스템이어서 로컬에서 돌리기에도 힘들고 - 이것저것 세팅을 해야 하고, IP도 변경해야 하고
서버에서 돌아가는 로그만 보고 있으니 디버깅하기가 참 힘들겠다는 생각이 든다.

그런데 이 프로그램을 로컬에서 간단하게 돌릴수 있으면, 콘솔에 변수를 찍어가며 데이터를 확인해 보면서 디버깅을 할 수 있지 않을까하는 생각이 든다.
자바에 익숙하지 않아도 눈으로 보면서 해보면 업무를 아니깐.

그래! 테스트를 작성하자!
로컬에서 언제든지 동작하는 테스트케이스를 작성해 두면 담당자들이 디버깅하기도 쉽고, 소스를 안보려고 회피하는 모습을 더이상 안봐도 된다.

- 클라이언트측에서 전송한 데이터를 처리하는 부분은 XML 데이터를 입력받을 수 있게 하고
- 데이터베이스 연결은 WAS에 종속적이지 않게 하고
- 에러가 발생하는 부분의 클래스만 생성해서 돌려보면 된다.

외부 시스템과의 연동 테스트시 로컬에서 진행하기???

상대방의 서버에서 SOAP 메세지를 보내오면 첨부된 XML 파일을 읽어서 데이터를 처리하는 기능이 있다.
이 XML 파일을 처리하면서 어떤 오류가 발생했다.

이 오류를 확인하기 위해서는 상대방에게 계속 동일 데이터를 매번 요청해야 한다.
이게 의심이 나면 수정하고 WAS 내렸다 올리고 전화해서 데이터 보내달라고 하고, 몇 분 기다렸다 데이터 보내주면 다시 디버깅하고.
상대방이 데이터를 바로 보내주면 다행이다.
그 사람들도 본업이 있는지라 1시간 뒤에 보내줄때도 있고, 가끔 시스템 장애로 다음 날 보내주는 경우도 있다.

SOAP 메세지는 문제없으니깐 XML 처리하는 부분만 테스트하자.
로그에서 첨부된 XML을 가져와서 이 부분만 테스트하자. - 데이터를 다시 보내달라고 할 필요없음.
- WAS 재기동 필요없음.
- 여기까지만 하다보니 문제점이 보였다.

우캬캬.

Tomcat 표준출력을 파일로 남기기

고객사에 모듈 업그레이드를 했는데 에러가 난다.
로그를 확인해야 하는데 로그가 없다.
클래스 로딩되는 상황을 확인해야 하는데 표준출력이 어디로 가는건지...

콘솔에서 starup.bat 를 실행시키거나 startup.bat 를 더블클릭해서 Tomcat을 시작하는 경우 표준출력이 콘솔에 출력되어서 지나간 로그를 확인하기가 힘들다.
(Tomcat 버전에 관계없이 당연한 현상임)


Tomcat이 새창으로 구동되어서 표준출력을 파일로 리다이렉션을 시켜도 파일이 제대로 남지 않는다.
로그가 많아서 필요한 로그는 새창에서 지나가 버림.
startup.bat, catalina.bat 를 이것저것 수정해도 안됨.

로그를 남기려면 새창을 띄우면 안됨.
새창을 띄우는 부분을 찾아서 수정하면 될거 같다.


또는
rem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% > c:/tomcat.log
goto end

이렇게 하면 표준출력이 파일로 떨어진다.
(서비스로 구동시키면 stdout.log, stderr.log 가 생길거야.)

- 회고
운영되는 서버를 왜 이렇게 구동시키지? 우....띠
예전에 이런 문제가 발생했을때 확실히 분석해서 방법을 알아뒀으면 오늘같은 고생은 안했을건데.

로그보고 에러 잡는 일이 남았다. 이제부터 진짜 일이지.

Mapping of MIME Types

MimeBodyPart.getContent() 의 리턴되는 객체가 String이였는데 JEUS 6에서는 에러가 발생한다.
java.lang.ClassCastException: javax.xml.transform.stream.StreamSource incompatible with java.lang.String

소스가 (String)MimeBodyPart.getContent() 이렇게 되어 있다.
확인 결과 JEUS의 라이브러리인 javaee.jar에서 발생하였고 기술지원을 받음.
getContent()는 MIME 타입에 따라 다른 객체를 리턴한다고 한다.

Tmax의 답변
기존 J2EE 1.4에서는 엄격하게 적용하지 않았지만, JavaEE 5 부터 JAX-WS 가 도입되면서 부터는
매핑을 엄격하게 적용하여 구현하고 있습니다.

 MIME Type  Java Type
 image/gif  java.awt.Image
 image/jpeg
 java.awt.Image
 text/plain
 java.lang.String
 multipart/*
 javax.mail.internet.MimeMultipart
 text/xml or application/xml
 javax.xml.transform.Source

MIME 타입이 xml 이므로 거기에 해당하는 객체가 리턴되고 적절한 처리를 하면 된다.

 
- 테스트케이스
- MIME 타입에 따른 처리가 되는지 확인하기 위해 javax.activation.debug 시스템 프로퍼티를 true로 하면 자세한 로그 내용을 볼 수 있다.



javap로 클래스 파일 버전 확인

> javap -verbose EDIReply
Compiled from "EDIReply.java"
public class com.edi.intra.EDIReply extends com.edi.intra.EDIBase
  SourceFile: "EDIReply.java"
  minor version: 0
  major version: 46
  Constant pool:
const #1 = class    #2;    //  com/edi/intra/EDIReply
const #2 = Asciz    com/edi/intra/EDIReply;

- ClassNotFoundException이 발생했음. 웹로직에서 런타임 버전과 컴파일된 클래스의 버전이 다른 경우에 발생하였다는 말에 javap 명령으로 버전 확인

[todo] os, 자바 시스템 프로퍼티를 확인해 볼 것. 현재 서버에 구동되고 있는 클래스파일의 버전 확인해 볼것.

ORA-01461: LONG 값은 LONG 열에만 입력할 수 있습니다

- K조합 G시스템 연계모듈(L건설)
ORA-01461: LONG 값은 LONG 열에만 입력할 수 있습니다

- CLOB 컬럼에 1287 byte의 데이터를 넣는데 에러가 발생

- 사용되는 드라이버의 위치를 찾아서 크기를 보니 1.33MB (1,397,543 바이트)
jar:file:/LConsB2B/jeus/jeus5/lib/datasource/ojdbc14.jar!/oracle/jdbc/driver/OracleDriver.class

- WAS : JEUS 5
Servlet : 2.4
JSP : 2.0
ServerInfo : Jeus Web Container

os.name=HP-UX
user.language=ko
java.version=1.4.2.17

- 최신 드라이버로 교체하면 됨.
그러나 여러 시스템이 해당 WAS를 사용하고 있어서 교체하기가 힘듬.
드라이버 위치도 JEUS/lib/datasource/ 임.

- KGModlue/WEB-INF/lib/ojdbc14.jar 를 사용하도록 클래스로딩 순서를 변경
jeus-web-dd.xml 에서 webinf-first 를 true로 설정하고 JEUS를 재기동해도 안됨.

- 확인해 본 결과 JEUS/lib/ 내에 있으면 JEUS 기동시 System Classloader 에 포함되므로 클래스로딩 순서를 변경할 수 없다.

- 결국은 JEUS/lib/datasource/ 의 오라클 드라이버를 교체해서 해결함.


시스템 정보 조회용 JSP

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.