컴퓨터/C#

[.net] jni4net 을 이용하여 c# .net 에서 .jar 파일 사용하기

dolhim 2016. 4. 26. 19:08


jni4net


이 라이브러리는 Java에서 C# 라이브러리를 사용하거나

C#에서 Java 라이브러리를 사용할 수 있도록 도와줍니다.


여기서는 C#에서 Java 라이브러리를 사용하는 방법에 대해 다룹니다.


크게 두 작업 절차를 거치는데,

첫째는, 라이브러리에 포함된 실행파일인 '프록시 파일'을 실행하면, 

브릿지 역할을 하는 자바, 닷넷 코드와 배치 파일 등을 생성해줍니다.

둘째는, 생성된 배치 파일을 실행하면, 코드를 컴파일하여 *.j4n.dll 파일과 *.j4n.jar 파일을 생성합니다.

라이브러리에 포함된 jni4net.dll 파일과, 생성된 *.j4n.dll 파일이 C#과 자바 사이의 다리 역할을 한다고 볼 수 있습니다.



하지만, jni4net 에서 프록시 과정을 잘 거치려면, jar 파일이 몇가지 조건을 만족해야 합니다.

제 경험상, 

    1. 패키지가 없으면 안됩니다. (이클립스에서 볼 때, .java 파일이 '(default package)'에 들어있는 것) 

    2. 패키지명이 소문자로만 이루어져야 합니다.

위 조건을 모두 만족하지 않으면, 프록시 및 빌드 과정에서 코드에 오류가 나거나, 컴파일에 실패하는 등 문제가 발생하게됩니다.  (이유는 잘..)



이러한 패키지 관련 문제를 최소화 하기 위해 아래에 j4n에 사용하기 위한 자바 파일을 만드는 과정부터 정리하였습니다.



1. 자바 파일 생성하기

 

 조건을 만족하는 *.jar 파일이 준비되어 있으면 아래 '2. jni4net 다운로드' 항목부터 진행합니다.



2. jni4net 다운로드

자바 파일이 준비되면 jni4net 홈페이지에 바이너리 파일과 툴을 최신 버전으로 다운 받습니다.

아래 페이지에서 링크를 클릭하면 SourceForge로 연결됩니다.



현재(16.04.26) 확인되는 최신 버전은 0.8.8.0(14.9.23 일자)로 이 버전 기준으로 작성되었습니다.



src 파일과 bin 파일 중에 아래와 같은 bin 파일을 선택합니다.



3. Proxygen 프로그램 실행

다운로드된 파일을 압축을 C드라이브 아래 혹은 바탕화면에 풀고, 아래와 같이 폴더 안에 자바 파일을 복사합니다.


그리고 탐색기 빈 공간에서 우클릭한 다음, 여기서 명령창 열기를 실행합니다. 명령창을 이용하여 bin 폴더 안에 있는 프록시 프로그램을 실행할 것입니다.


창에 명령어를 입력합니다. 위에서 복사한 자바 파일 이름을 알맞게 입력해야 합니다. 

1
 bin\proxygen.exe [자바 파일 이름].jar -wd .\
cs


잘 실행되면 아래와 같은 문구를 확인할 수 있습니다. 

이와 다른 문구가 뜬다면 명령어에서 파일의 경로가 틀렸거나, C드라이브 외의 위치에서 실행했기 때문입니다.



작업 폴더에 아래와 같이 폴더와 파일이 생깁니다.


4. C# 프로젝트 생성

이제 C# 코드를 작성합니다.


비주얼 스튜디오에서 프로젝트를 생성한 다음, 아래와 같이 코드를 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using net.sf.jni4net;
 
namespace Jni4netTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var bridgeSetup = new BridgeSetup();
            bridgeSetup.AddAllJarsClassPath(".");
            // 'JNIException 예외' 발생 막아줌..
            bridgeSetup.IgnoreJavaHome = true;
            bridgeSetup.Verbose = true;
            Bridge.CreateJVM(bridgeSetup);
 
            Console.ReadLine();
        }
    }
}
cs

몇 가지 발생하는 에러는 jni4net라이브러리를 추가하지 않았기 때문인데, 일단 무시하고 넘어갑니다.




5. Build.cmd 명령 실행

실행 폴더로 이동하여 jni4net라는 이름으로 폴더를 생성하고, 

그 안에 jni4net 작업 폴더에서 'bin', 'sample' 폴더 및 불필요한 'txt', 'xml'파일을 제외한 파일들을 복사합니다.



그러면 C# 실행 폴더가 아래와 같이

Debug 아래에 jni4net 폴더와 C#빌드 결과 파일이 있고,

 jni4net 폴더 아래에 복사한 파일이 있는 구성이어야 합니다.


위와 같다면 ,

jni4net/lib 폴더의 모든 파일들을, C# 폴더에 복사합니다. build.cmd 파일을 실행하기 위함입니다.


그리고, jni4net 폴더안에 build.cmd 파일을 텍스트 편집기로 열어 수정합니다.

여기서 고려해야할 사항은, *.class, *.jar 파일들의 경로와 아래 csc 명령어에서 사용되는 csc.exe 파일 위치 입니다. 실행하는 컴퓨터 환경에 알맞게 수정해야 합니다. 여기서는 .net 4.0 버전을 사용하도록 작성되었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@echo off
if not exist target mkdir target
if not exist target\classes mkdir target\classes
 
 
echo compile classes
javac -nowarn -d target\classes -sourcepath jvm -cp "JavaWorld.jar""lib\jni4net.j-0.8.8.0.jar""jvm\javaworld\Introduction_.java" 
IF %ERRORLEVEL% NEQ 0 goto end
 
 
echo JavaWorld.j4n.jar 
jar cvf ..\JavaWorld.j4n.jar  -C target\classes "javaworld\Introduction_.class"  > nul 
IF %ERRORLEVEL% NEQ 0 goto end
 
 
echo JavaWorld.j4n.dll 
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /nologo /warn:0 /t:library /out:..\JavaWorld.j4n.dll /recurse:clr\*.cs  /reference:"lib\jni4net.n-0.8.8.0.dll"
IF %ERRORLEVEL% NEQ 0 goto end
 
 
:end
cs


build.cmd 파일을 클릭하여 실행하면, c# 실행 폴더에 .j4n.dll 파일과 .j4n.jar 파일이 생성됩니다.


만약 안될 경우, build 파일에서 파일의 경로가 알맞게 들어갔는지 확인합니다.

csc 명령어를 사용할 수 없다고 뜰 경우, csc.exe 파일의 위치가 잘못 되었을 가능성이 있습니다.



6. C# 코드 수정

다음으로, 비주얼 스튜디오로 돌아와서, 

프로젝트에 실행경로로부터 'jni4net.n-0.8.8.0.dll'파일을 참조 추가합니다.

그리고, 빌드 명령으로부터 생성된 '[자바 프로젝트명].j4n.jar' 파일도 참조 추가합니다.


코드를 아래와 같이 수정하고 프로그램을 실행합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using net.sf.jni4net;
 
namespace Jni4netTest
{
    class Program
    {
 
        static void Main(string[] args)
        {
            var bridgeSetup = new BridgeSetup();
            bridgeSetup.AddAllJarsClassPath(".");
            // [임시] 'JNIException 예외' 발생 막아줌..
            bridgeSetup.IgnoreJavaHome = true;
            bridgeSetup.Verbose = true;
            Bridge.CreateJVM(bridgeSetup);
 
            // 어셈블리 등록. typeof 안에는 '네임스페이스(패키지)명.클래스명' 형식으로 입력해야함.
            Bridge.RegisterAssembly(typeof(javaworld.Introduction).Assembly);
 
            // 자바 파일을 사용하는 코드
            javaworld.Introduction.Say();
            javaworld.Introduction.Say("drlee");
 
            Console.ReadLine();
        }
    }
}
 
cs



추가. 예외 및 에러 발생


1. JNIException이(가) 처리되지 않았습니다.



 - .jar 파일 생성시 패키지가 없을 경우.

 - .jar 파일의 패키지 명에 대문자가 포함되어 있을 경우.

 - .jar 파일과 .j4n.dll 이 같이 생성한 파일이 아닌 경우.


등이 있습니다.

이럴땐, .jar 파일을 다시 생성해야합니다. 



2. 만약, JAVA_HOME 설정이 되지 않았으면 jre(혹은 jdk)를 사용할 수 없다고 뜰 수도 있습니다.




실행 결과 




참고 : 

[JAVA] C# Library Call by Java Bridge (이 예제와 반대로 Java 에서 .net 라이브러리를 사용한 방법입니다.)