如何在 C#.NET 呼叫 Java 類別庫 (使用 IKVM.NET)
C#.NET 與 Java 是兩種不一樣的程式語言,這兩種程式語言都屬於物件導向程式,寫法有許多相似之處,最近有一位 Java 工程師來詢問我,他最近剛接觸 C# 程式,因為專案一些邏輯寫在 Java 裡面,也好奇是否能在 C# 呼叫在 Java 寫好的 .jar 檔類別庫。
關於如何在 C# 引用 Java 類別庫,我會推薦 .NET Framework 的第三方類別庫 IKVM.NET,它可以將 .jar 轉成 .dll,並在 .NET Framework 環境下使用。
首先我想先說一下,因為這是兩種不一樣的語言與架構,基礎架構不同的情況下,本就無法互通,也無法互相引用。
而我這次使用的是第三方類別庫 IKVM.NET,它是將 Java JDK 環境下的類別轉成 .NET 類別,好讓我們在 .NET 引用 IKVM.NET 元件後,可以認識這些 Java JDK 類別。
如果在 Java 編譯的 .jar 檔本身語法單純都使用 JDK 類別庫的話,可以透過 IKVM 將 .jar 轉成 .dll 給 .NET 引用,那轉成的 .dll 比較容易正常執行。
但如果 .jar 檔本身又引用外部 .jar 檔,那轉檔失敗率很高,還需要特別處理外部 .jar 檔的問題,轉檔過程會變的相當困難。
而 IKVM.NET 本身處理 Java 轉 .NET 的程式碼穩定性,我們無法掌握品質,無法確定方法都正確執行且回傳值與 Java JDK 環境一樣,所以需要使用的朋友請自行考量使用風險喔。
以下會介紹怎麼將 .jar 轉成 .dll 給 .NET 使用,有需要的朋友可以試試看。
Contents
製作一個測試 .jar 檔
首先我們先在 Java 環境下,寫一個簡單的類別及幾個簡單的方法,然後再輸出成 .jar 檔。
安裝 JDK
如果你還沒有 Java 環境的話,需要先下載 JDK 安裝。
可至官方下載 JDK。
我下載的版本是 jdk1.8.0_321。
下載後直接安裝,安裝完成之後,在預設目錄 C:\Program Files\Java\jdk1.8.0_321 會有 JDK 主程式。
接著設定環境變數,在環境變數裡面設定 JAVA_HOME 的 JDK 路徑。
然後在 Path 裡面加入新環境變數 %JAVA_HOME%\bin。
測試 JDK 安裝是否完成,可以在 cmd 裡面輸入 java –version 確認是否安裝成功。
第一次安裝 JDK 的話,如果要接著使用下面的 javac 指令的話,需要先重開機才會生效喔。
測試 java 檔
接著我們新增一個 java 檔案,其中包含幾種不同的測試方法。
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 30 31 32 33 34 35 36 37 38 39 40 |
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.io.PrintWriter; public class JavaLibraryTest{ public String getDate(){ Date date = new Date(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = (df.format(date)).toString(); return dateStr; } public int[] getArray(){ int[] arr = new int[] {58, 1, 50, 23, 55, 78, 19, 3, 9, 29}; return arr; } public HashMap getMap(){ HashMap map = new HashMap(); map.put("A", "111"); map.put("B", "222"); return map; } public boolean writeFile(){ try{ PrintWriter writer = new PrintWriter("C:\\temp\\test.txt", "UTF-8"); writer.println("The first line"); writer.println("The second line"); writer.close(); return true; } catch (Exception e){ System.out.println("An error occurred."); e.printStackTrace(); return false; } } } |
此類別包含 4 種不同的方法,然後儲存至 C:\Temp\JavaLibraryTest.java
編譯 Java
接著利用 cmd 編譯此 Java 檔。
在 cmd 輸入以下指令:
cd C:\Temp
javac JavaLibraryTest.java
執行完會產生一個 JavaLibraryTest.class 檔。
接著再下指令將此 JavaLibraryTest.class 直接打包成 JavaLibraryTest.jar
jar cvf JavaLibraryTest.jar JavaLibraryTest.class
完成後就會有 JavaLibraryTest.jar 出現了。
將 .jar 檔轉成 .dll
接著會實作將剛剛的 JavaLibraryTest.jar 轉成 .NET 可以讀取的 .dll 檔。
這裡會使用到 IKVM.NET 這個元件。
IKVM.NET 是讓 .NET C# 程式碼可以呼叫 Java 類別庫的一種實現方式。
可以在官網下載主程式,但不知道什麼原因,官網無法開啟網站了。
所以這邊我提供我手上從其他位置下載過的轉碼主程式,我這邊可以提供 2 種版本:
ikvmbin-8.1.5717.0.zip 此版本支援 JDK 1.8 的版本。
ikvmbin-7.2.4630.5.zip 此版本支援 JDK 1.7 的版本。
你可以依照你使用的 JDK 版本來下載對應的主程式。
以下的示範是使用 ikvmbin-8.1.5717.0 這個版本的程式。
下載解壓縮後放在 C:\Temp\ikvm-8.1.5717.0。(可以自行決定位置,只要指令指對路徑即可。)
接著把剛剛產生的 JavaLibraryTest.jar 放到 bin 目錄下,
然後在 cmd 輸入以下指令:
C:\Temp\ikvm-8.1.5717.0\bin
ikvmc -target:library JavaLibraryTest.jar
執行後會在 bin 目錄下多一個 JavaLibraryTest.dll 的檔案,這就是要給 .NET 呼叫的檔案。
在執行 .jar 轉 .dll 的過程中,可能會出現很多的錯誤,通常都是因為參照來源的問題,在 java 如果引用愈多的 library,就會有很多的 warning 出現,IKVM 會試著找各種對應的 library,但也會有找不到的問題,當找不到的話,實際上呼叫 .dll 就容易發生錯誤。
C#.NET 引用呼叫 Java 類別
接著我們就回到 Visual Studio 2022 的環境下執行。
我這裡用簡單的 ConsoleApp 示範,用 ASP.NET MVC 或 WinForm 程式都可以,但是要注意只能在 .NET Framework 下執行。
VS 安裝 IKVM.NET 套件
執行專案的「參考 > 管理 NuGet 套件」。
搜尋 ” IKVM” 可以找到套件,這裡要安裝 IKVM 的版本,選擇版本要跟剛剛把 .jar 轉 .dll 的版本相同,我示範用的是 ikvm-8.1.5717.0,所以在 NuGet 裡面也要選 8.1.5717 版本安裝。
載入 .dll 類別庫
把剛剛用 .jar 檔轉好的 JavaLibraryTest.dll 檔案,複製到專案的目錄底下。
執行專案的「參考 > 加入參考」。
再選「瀏覽」,把剛剛的 JavaLibraryTest.dll 檔案載入專案裡面。
載入後會看到參考類別已經加入這個 .dll。
對參考類別點兩下後,可以看到裡面提供的方法,跟我們在 Java 建立的方法一樣。
執行 Java 方法
執著就可以寫程式,呼叫 Java 裡面的方法了。
以下是我呼叫的測試語法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
JavaLibraryTest javaTest = new JavaLibraryTest(); string date = javaTest.getDate(); Console.WriteLine(date); int[] array = javaTest.getArray(); Console.WriteLine(string.Join(", ", array)); HashMap map = javaTest.getMap(); Console.WriteLine(map); bool isWrite = javaTest.writeFile(); Console.WriteLine(isWrite); Console.ReadLine(); |
因為引用了 IKVM.NET 變為專案也認識了 Java 類別庫,所以在 HashMap 可以 using java.util;
執行後就會出現從 Java 方法來的結果了。
相關學習文章
如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝