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