下面的應用程序將實現從http服務器裝載并執行一個jar文件的功能,比如你的Jar文件的地址為hello.jar。要實現這個功能我們應該首先建立與這個文件的連接然后通過MANIFEST的信息描述得到Main-Class的值,最后裝載并運行這個class。這里面需要用到java.net和反射的一些重要知識。這個應用程序由兩個類組成:JarClassLoader和JarRunner。
JarClassLoader擴展了URLClassLoader,它有一個成員為URL類型的url變量。
public JarClassLoader(URL url)
{
super(new URL[] { url });
this.url = url;
}
它的兩個重要方法是getMainClassName()和invokeClass(),其中前者的目的是通過URL和jar取得連接后,讀取MANIFEST的Main-Class屬性從而得到應用程序的入點,這非常重要。得到入點后我們就可以通過反射機制裝載和運行得到的主類。
public String getMainClassName() throws IOException {
URL u = new URL("jar", "", url + "!/");
JarURLConnection UC = (JarURLConnection)u.openConnection();
Attributes attr = uc.getMainAttributes();
return attr != null
? attr.getValue(Attributes.Name.MAIN_CLASS)
: null;
}
public void invokeClass(String name, String[] args)
throws ClassNotFoundException,
NoSuchMethodException,
InvocationTargetException
{
Class c = this.loadClass(name);
Method m = c.getMethod("main", new Class[] { args.getClass() });
m.setaccessible(true);
int mods = m.getModifiers();
if (m.getReturnType() != void.class !Modifier.isStatic(mods)
!Modifier.isPublic(mods)) {
throw new NoSuchMethodException("main");
}
try {
m.invoke(null, new Object[] { args });
} catch (IllegalAccessException e) {
// This should not happen, as we have disabled access checks
}
}
URL u = new URL("jar", "", url + "!/");
JarURLConnection uc = (JarURLConnection)u.openConnection();
這兩段代碼構造一個JarURLConnection的實例,注重!/的分隔符的意思是這個url表示的是整個jar文件。這樣我們就建立了和jar文件的通信。方法中的后面兩句話得到jar文件的主類。在invokeClass方法中,我們首先通過ClassLoader的方法得到包括程序入口的主類,然后得到main方法,判定main方法為我們需要的方法后則調Method的invoke方法執行這個應用程序。
新聞熱點
疑難解答