본문 바로가기

Coder Life/Weblogic

Weblogic 8.1 <=> Weblogic 10g 간의 RowSet 통신 해결방안






※ 작업전 문제사항 체크
Weblogic 8.1(이하 8.1)을 구동하는 JDK는 1.4, 
Weblogic 10g(이하 10g)를 구동하는 JDK는 1.6 이다.

사용하려는 rowset라이브러리는 jdk1.4때 구현 되어,
jdk1.5 때 정식으로 포함되었다. 

여기서 모든 문제가 발생된다.
jdk1.4에서 rowset을 구현하려면, java.sun.com에서 rowset.jar를 다운로드 받아야 한다.
(jdbc_rowset_tiger-1_0_1-mrel-ri.zip에 포함)

하지만, 이 라이브러리에는 문제가 있다.
내부에서 사용하는 properties를 읽어 들이는데, 소스상에서는 국가별 지정코드가 있는데 반해,
실제 코드에는 ko에 해당하는 코드가 존재하지 않는다
즉, 버그다.

해당하는 jar를 풀어서 properies를 추가하고 다시 jar를 묶어주면 문제는 해결될듯 보이나,
해결되지 않는다.

rowset.jar와 jdk1.6의 rowset이 같지 않다.

대체 방안은 weblogic의 rowset라이브러리나, oracle의 jdbc드라이버를 이용하는 방법이 있으나,
둘다 버전이 각각 다르므로, 해당사항 없고 버그도 동일하게 존재한다. 특히 8.1은 rowset의 동일 버그가 존재한다.
뭐, weblogic.jar를 풀어서 다시 묶겠다면 말리지는 않겠다. (그렇다고 해결되는것은 아니다)


※ 발생 오류 종류
java.lang.NullPointerException
java.rmi.UnmarshalException
java.io.InvalidClassException + serialVersionUID
java.rmi.RemoteException

※ 해결방법
jdk1.6을 1.4에 맞출 방법은 없다. jdk1.6의 rowset 라이브러리들을 가지고 
1.4에 맞는 rowset.jar를 만든다.(ㅋ 심플하다. 작업은 그렇게 심플하지 않는다.)

다음 순서에서 차근차근 풀어가면 해결이 될것이다.

1. rowset.jar 만들기
   위에서 말한 것처럼, jdk1.6의 소스를 가지고 1.4버전용 rowset.jar를 만든다.
   소스는 jdk1.6에 포함된 src를 살펴봐도 없을것이다. --+
   openjava로 가서 rt.jar에 해당되는 소스를 구한다.
   해당패키지는 com.sun.rowset.* , javax.sql.rowset.* 이다.
   
   모두 구했으면, 프로젝트를 jdk1.4에 맞추고 해당 프로그램을 추가하고 빌드하면, 수천개의 버그를 볼수 있을것이다.
   하나씩 해결해 가면 될것이다. 
   대부분이 jdk1.4에서 1.6으로 넘어가면서 추가된 메소드들이 대부분일것이다.
   
   기억나는건 MessageFormat과 SQLNotSupport..Exception 이다. 
   MessageFormat은 1.4버전의 api javadoc을 보면, 유사메소드가 있을것이다. 바꿔준다.
   SQLNotSupport..Exception은 SQLException으로 바꿔준다.
   그밖의 것들은 잘 찾아서 하길 바란다.
   
   그렇게 해서 만들어서 jar 를 묶에서 패키지에 올리면 된다.
   
2. java.io.InvalidClassException + serialVersionUID 잡기
   테스트 해보면  알겠지만 InvalidClassException이 발생한다.
   RMI로 Call했을때, 클래스 serialize할때 발생하는 문제이다.
   serialize할때, serialVersionUID를 생성한는데, 그게 로컬과 리모트서버가 다르다는 얘기다.
   
   로컬(jdk1.6)은 바꿔 줄수 없으므로, 리모트서버(jdk1.4+rowset.jar)를 바꿔줄수밖에 없다.
   해당 클래스 찾아서, 로컬의 serialVersionUID를 리모트에 다음처럼 셋팅해준다.
   
   static final long serialVersionUID = -3897405922026703193L;
   
   이런식으로 하나씩 해결해 나간다. 뭐 대부분은 이미 셋팅되어 있기에 한 십여개만 해결해 주면 된다.
   
   $JAVA_HOME/bin/serialver -classpath $CLASSPATH $classname   
   이런식으로 미리 serialVersionUID 확인할수도 있으니 방법은 알아서 하길 바란다.

3. 끝

※결과
동일한 was, 동일한 jdk버전, 동일한 oracle버전의 동일한 환경이 아니면 rowset을 쓰지 마라!!!
rmi call할때, 데이터를 옮기는 기본은 VO(Value Object) 객체이다. 
VO를 써야 할곳에서 RowSet이나 ResultSet을 가지고 다니지 않는것이 상책이다.