zoukankan      html  css  js  c++  java
  • 运行jar应用程序引用其他jar包的四种方法

    方法一、使用Bootstrap Classloader来加载这些类。

    我们可以在运行时使用如下参数:

    -Xbootclasspath:完全取代系统Java classpath.最好不用。
    -Xbootclasspath/a: 在系统class加载后加载。一般用这个。
    -Xbootclasspath/p: 在系统class加载前加载,注意使用,和系统类冲突就不好了.

    win32     java -Xbootclasspath/a: some.jar;some2.jar;  -jar test.jar

    unix          java -Xbootclasspath/a: some.jar:some2.jar:  -jar test.jar

    win32系统每个jar用分号隔开,unix系统下用冒号隔开

    方法二、使用Extension Classloader来加载

    你可以把需要加载的jar都扔到%JRE_HOME%/lib/ext下面,这个目录下的jar包会在Bootstrap Classloader工作完后由Extension Classloader来加载。非常方便,非常省心

     方法三、还是用AppClassloader来加载,不过不需要classpath参数了

    我们在MANIFEST.MF中添加如下代码:

    Class-Path: lib/some.jar

    lib是和test.jar同目录的一个子目录,test.jar要引用的some.jar包就在这里面。

    然后测试运行,一切正常!

    如果有多个jar包需要引用的情况:

    Class-Path: lib/some.jar lib/some2.jar

    每个单独的jar用空格隔开就可以了。注意使用相对路径。

    另:如果META-INF 下包含INDEX.LIST文件的话,可能会使Class-Path配置失效。INDEX.LIST是Jar打包工具打包时生成的索引文件,删除对运行不产生影响。

    方法四、自定义Classloader来加载板面的做法和配料

    这种方法是终极解决方案,基本上那些知名java应用都是那么干的,如tomcat、jboss等等。

    java应用环境中不同的class分别由不同的ClassLoader负责加载。
    一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:


    Bootstrap ClassLoader      负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等Extension ClassLoader       负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和classApp ClassLoader           负责加载当前java应用的classpath中的所有类。

    其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。
    Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。

    Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系如下:

    Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。

    但是这并不是继承关系,只是语义上的定义,基本上,每一个ClassLoader实现,都有一个Parent ClassLoader。

    可以通过ClassLoader的getParent方法得到当前ClassLoader的parent。Bootstrap ClassLoader比较特殊,因为它不是java class所以Extension ClassLoader的getParent方法返回的是NULL。

    了解了ClassLoader的原理和流程以后,我们可以试试自定义ClassLoader。

    关于自定义ClassLoader:

    由于一些特殊的需求,我们可能需要定制ClassLoader的加载行为,这时候就需要自定义ClassLoader了.

    自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式。

    主要可以扩展的方法有:

    findClass          定义查找Class的方式

    defineClass       将类文件字节码加载为jvm中的class

    findResource    定义查找资源的方式

    如果嫌麻烦的话,我们可以直接使用或继承已有的ClassLoader实现,比如

    • java.net.URLClassLoader

    • java.security.SecureClassLoader

    • java.rmi.server.RMIClassLoader

    • sun.applet.AppletClassLoader

    Extension ClassLoader 和 App ClassLoader都是java.net.URLClassLoader的子类。

    这个是URLClassLoader的构造方法:

    public URLClassLoader(URL[] urls, ClassLoader parent)

    public URLClassLoader(URL[] urls)

    urls参数是需要加载的ClassPath url数组,可以指定parent ClassLoader,不指定的话默认以当前调用类的ClassLoader为parent。

    1
    2
    3
    4
    5
    6
    ClassLoader classLoader = new URLClassLoader(urls);  
    Thread.currentThread().setContextClassLoader(classLoader);  
    Class clazz=classLoader.loadClass("com.company.MyClass");//使用loadClass方法加载class,这个class是在urls参数指定的classpath下边。  
       
    Method taskMethod = clazz.getMethod("doTask", String.class, String.class);//然后我们就可以用反射做些事情了  
    taskMethod.invoke(clazz.newInstance(),"hello","world");

    由于classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。

    所以,当我们自定义的classloader加载成功了com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。

  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/beef/p/7455594.html
Copyright © 2011-2022 走看看