java解析jar文件,读取并进行调用

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

java解析jar⽂件,读取并进⾏调⽤
简单介绍了如何使⽤java.util.jar包提供的API操作jar⽂件,下⾯通过⼀个相对复杂的例⼦讲述⼀些Jar⽂件相关的⾼级应⽤。

仔细读读这篇⽂章并参考⼀下相关的java doc会对你学习java语⾔有很⼤的帮助。

下⾯的应⽤程序将实现从http服务器装载并执⾏⼀个jar⽂件的功能,⽐如你的Jar⽂件的地址为。

要实现这个功能我们应该⾸先建⽴与这个⽂件的连接然后通过MANIFEST的信息描述得到Main-Class的值,最后装载并运⾏这个class。

这⾥⾯需要⽤到和反射的⼀些重要知识。

这个应⽤程序由两个类组成: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(.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⽅法执⾏这个应⽤程序。

下⾯是源程序的代码
import .URL;
import .URLClassLoader;
import .JarURLConnection;
import ng.reflect.Method;
import ng.reflect.Modifier;
import ng.reflect.InvocationTargetException;
import java.util.jar.Attributes;
import java.io.IOException;
class JarClassLoader extends URLClassLoader {
private URL url;
public JarClassLoader(URL url) {
super(new URL[] { url });
this.url = url;
}
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(.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
}
}
}
import java.io.IOException;
import .URL;
import .MalformedURLException;
import ng.reflect.InvocationTargetException;
/**
* Runs a jar application from any url. Usage is 'java JarRunner url [args..]' * where url is the url of the jar file and args is optional arguments to
* be passed to the application's main method.
*/
public class JarRunner {
public static void main(String[] args) {
if (args.length < 1) {
usage();
}
URL url = null;
try {
url = new URL(args[0]);
} catch (MalformedURLException e) {
fatal("Invalid URL: " + args[0]);
}
// Create the class loader for the application jar file
JarClassLoader cl = new JarClassLoader(url);
// Get the application's main class name
String name = null;
try {
name = cl.getMainClassName();
} catch (IOException e) {
System.err.println("I/O error while loading JAR file:");
e.printStackTrace();
System.exit(1);
}
if (name == null) {
fatal("Specified jar file does not contain a 'Main-Class'" +
" manifest attribute");
}
// Get arguments for the application
String[] newArgs = new String[args.length - 1];
System.arraycopy(args, 1, newArgs, 0, newArgs.length);
// Invoke application's main class
try {
cl.invokeClass(name, newArgs);
} catch (ClassNotFoundException e) {
fatal("Class not found: " + name);
} catch (NoSuchMethodException e) {
fatal("Class does not define a 'main' method: " + name);
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
System.exit(1);
}
}
private static void fatal(String s) {
System.err.println(s);
System.exit(1);
}
private static void usage() {
fatal("Usage: java JarRunner url [args..]");
}
}
我们编写⼀个简单的HelloWorld程序,然后打个jar包,注意你的jar包内的MANIFEST⽂件⼀定要包括Main-Class: HelloWorld,否则的话找不到程序的⼊⼝。

把它放在⼀个web服务器上⽐如。

编译源程序后执⾏
java JarRunner (可以含有参数)在控制台我们会看到hello world的字样输出!。

相关文档
最新文档