SILENTSOFT
Published on

Java에서 ocx 호출 삽질기 - 1부

Authors

Java로 개발하는 클라이언트 프로그램에서 ocx 파일을 참조해야 할 일이 생겼다. 그래서, Java와 Native간 다리(Bridge)를 놓아주는 라이브러리를 알아보던 중 Jacob과 j-interop을 찾을 수 있었고, 둘다 괜찮은 라이브러리지만 Jacob이 더 간결해보여서 COM 오브젝트의 CLSID로 ocx 호출에 성공했다.

단 3줄의 코딩으로 ocx를 땡겨올 수 있다니.. 감동 그 자체였다.

문제는 여기서 부터..

내가 사무실에서 쓰는 노트북은 x86이다. 나는 ocx 호출에 문제가 없었지만, x64 머신에서는 Jacob이든 j-interop이든 잘 동작하지 않았다. COM 오브젝트를 찾을 수 없다거나, 메소드를 못찾는다거나 오브젝트를 생성하다가 에러를 뱉어내곤 하였다.

OK 좋아. 눈에는 눈, 이에는 이.

Java로는 안되나 싶어서 Native로 해결해보기로 하였다.

VB6, C++, C#순으로 삽질해보기로 했다. (Java 프로그램인데.. 이거 하나 호출하자고 C#을 쓰면 .NET이 안깔린 환경에서는 .NET을 별도로 설치해야하기 때문에 C#은 가장 최후의 수단으로 정했다.)

우선, 가장 간단하게 해결할 수 있는 VB6으로 선택했다. VB6에서 ocx를 참조해서 Wrapping한 뒤, 컴파일했다. 그런데, Java에서 JNA로 땡겨오려니 잘 되지않는다..? 한참을 구글링해보아도 명쾌한 답을 찾을 수 없었고.. Java와 VB6은 궁합이 잘 안맞나보다.. 하고 결론을 내리고 깔끔하게 포기했다.

그럼 두번째. C++. 사실 C++은 손놓은지 5년이나 지났기 때문에 그동안 Java로만 개발하다가 다시 C++ 코드를 보는 순간 대략 머리가 멍해졌다. (..어버버ㅓ...) 어찌됐건, 우여곡절 구글링 끝에 MFC dll로 만들어서 COM 오브젝트를 쉽게 땡겨올 수 있었다.

내 노트북이 x86이니까 x64로 컴파일하고 x64 머신에서 실행해보았으나.. 또 안된다.. CoCreateInstance(..)에서 자꾸 뻗는다.. (여기서 깨달아야 했으나, 내 지식이 얕았던 관계로 눈치채지 못했다.)

....? 이게 왜 안되지??? C#으로 땡겨오기만 해볼까..? 그렇게 미루었던 .NET이지만, 확인사살을 안할래야 안할 수가 없었다. 급하게 클래스 라이브러리 프로젝트를 생성하고 DLL로 컴파일 한 뒤 여러번의 삽질 끝에 x86에서 동작 확인 OK. 그러나 역시 마찬가지로 x64는 fail...

............??????????????????????

다시 원점으로 돌아와서 구글링을 해보려는 찰나, 같이 일하는 분이 JRE를 x86으로 바꾸면 될 것 같은데... 라고 얘기한다. (사실 이게 아니길 바랬다. x64머신에서도 무조건 x86 JVM을 써야한다니..)

그런데.. 정말 그렇게 하니까 잘 돌아간다.. 단지 이클립스에서 JRE만 x86으로 맞춰주고 실행하니 잘 돌아간다... 심지어 처음에 썻던 Jacob도 잘 돌아간다... 아주 깔끔하게..

원인은 간단했다. ocx 파일이 x86머신에서 컴파일되어서 x64 프로세스에선 로딩이 안됐던 것이다. (난 x86머신에서 자바로만 북치고 장구치고 했으니.. x64는 그동안 아웃 오브 안중이었다.)

그럼.. 지금 당장은 x64머신이라도 x86 JVM으로 돌리고, 나중에 platform.arch가 아닌 os.arch를 참조해서 동작하는 3rd party 라이브러리를 쓰게되는 날이 오면 그때가서 다시 검토하는걸로 일단락 지으려고 했다.

아까 JRE를 바꾸면 될 것같다고 말씀하신 분의 한 마디가 없었더라면 말이다.

"x86으로 exe 만들고 콜하는게 더 나을수 있어요."

그래.. 마지막으로 삽질 한번만 더 해보자.

exe에서 ocx를 참조하고, 자바에서 IPC나 RPC로 exe랑 통신하는 삽질은 2부에서...