zoukankan      html  css  js  c++  java
  • java 解析jar 文件,读取并进行调用

    在应用程序中处理Jar文件简单介绍了如何使用java.util.jar包提供的API操作jar文件,下面通过一个相对复杂的例子讲述一些Jar文件相关的高级应用。仔细读读这篇文章并参考一下相关的java doc会对你学习java语言有很大的帮助。

        下面的应用程序将实现从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方法执行这个应用程序。

        下面是源程序的代码

    import java.net.URL;
    import java.net.URLClassLoader;
    import java.net.JarURLConnection;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.lang.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(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
     }
        }
    
    }
    import java.io.IOException;
    import java.net.URL;
    import java.net.MalformedURLException;
    import java.lang.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服务器上比如http://localhost/hello.jar。编译源程序后执行
    java JarRunner http://localhost/hello.jar (可以含有参数)在控制台我们会看到hello world的字样输出!

  • 相关阅读:
    win7下的vxworks总结
    ubuntu 无法获得锁 /var/lib/dpkg/lock
    项目中用到了的一些批处理文件
    win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM
    使用opencv统计视频库的总时长
    January 05th, 2018 Week 01st Friday
    January 04th, 2018 Week 01st Thursday
    January 03rd, 2018 Week 01st Wednesday
    January 02nd, 2018 Week 01st Tuesday
    January 01st, 2018 Week 01st Monday
  • 原文地址:https://www.cnblogs.com/tankaixiong/p/2937323.html
Copyright © 2011-2022 走看看