猛禽洛的程式筆記庫

[Java] 動態載入Jar並呼叫裡面的Class方法

Java本身是不允許呼叫外部的程式碼,因為這樣會造成安全性問題(例如程式碼被掉包,偷偷執行惡意程式碼),不過在有些場合還是有動態呼叫Jar檔的需求,所以雖然不建議,但還是可以用反射的方式來執行我們(下載)的Jar檔。

1.建立Lib Jar

首先製作一個我們的Lib,本範例會用2個方法來展示如何執行方法與傳遞資料。

假設有一個DragonLib,裡面有兩個方法:sayHello、byteToHex(byte)

DragonLib.java

public class DragonLib {
    public String sayHello(){
        return "grrrrrr";
    }

    public String byteToHex(byte b){
        return (""+"0123456789ABCDEF".charAt(0xf&b>>4)+"0123456789ABCDEF".charAt(b&0xf));
    }
}

建立好此Java檔後,進行編譯與打包:

使用cmd,將路徑移動到此java檔資料夾下,進行編譯:

javac .\DragonLib.java

這樣就會產出編譯後的DragonLib.class

打包DragonLib.class:

jar cf MyLibrary.jar .\DragonLib.class

這樣就會打包出MyLibrary.jar了!

2.在Java主程式中,載入並使用MyLibrary.jar

try {
	// Jar的路徑
	File jarFile = new File("C:\\Users\\Downloads\\MyLibrary.jar");
	URL jarUrl = jarFile.toURI().toURL();
	URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl});
	
	// 指定class
	Class<?> myLibraryClass = Class.forName("DragonLib", true, classLoader);
	// 透過反射建立實例
	Object myLibraryInstance = myLibraryClass.getDeclaredConstructor().newInstance();

	// 之後就可以開始呼叫Jar內的方法
	// 透過反射呼叫 sayHello 方法,強轉成return回來的型別(因為Lib是自己寫的,就會知道要用什麼型別來接)
	String bb = (String) myLibraryClass.getMethod("sayHello").invoke(myLibraryInstance);
	// 會印出我們Lib中所寫的"grrrrrr"
	System.out.println(bb);
	
	// 傳遞參數進去運算後返回
	// 待傳遞的參數
	byte tt = (byte)0xAF;
	// 指定方法名稱與參數型別
	Method hexMethod = myLibraryClass.getMethod("byteToHex", byte.class);
	// 把實例跟參數丟進方法裡
	String aa = (String)hexMethod.invoke(myLibraryInstance, tt);
	// 印出"AF"
	System.out.println(aa);
	
}catch (Exception e){
	e.printStackTrace();
}

以上就是與外部Jar互動的方法,這樣就能夠從遠端下載Jar並執行特定的程式碼了。

-END-

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *