<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 28, comments - 37, trackbacks - 0, articles - 0
         最近這些天學習了classLoader的原理, 原因是因為服務器上的一個java進程啟動時加載兩個不同版本的jar包, 含有相同名字的類, 而且服務端的jar包排在前面, 我上傳的jar包排在后面, 于是每次都使用服務端的jar包, 我的jar包便無法生效, 因此希望修改classLader, 讓它按相反的順序加載jar包.
         網上查閱了classLoader的原理, 分析jvm默認使用AppClassLoader加載classpath中的類, 因此目標很明確, 替換它就行了, 找到一個參數
    java.system.class.loader, 只需要在啟動java進程的時候把它設置為自己的類就行.
         開始寫自己的classLoader, 參考URLClassLoader與網上的介紹, 寫了一個簡單的,上代碼:
      1 package org.taobao.yuling.testClassLoader;
      2 
      3 import java.io.*;
      4 import java.lang.reflect.*;
      5 import java.net.MalformedURLException;
      6 import java.net.URL;
      7 import java.net.URLClassLoader;
      8 import java.nio.ByteBuffer;
      9 import java.security.AccessControlContext;
     10 import java.security.AccessController;
     11 import java.security.CodeSigner;
     12 import java.security.CodeSource;
     13 import java.security.PermissionCollection;
     14 import java.security.PrivilegedAction;
     15 import java.security.SecureClassLoader;
     16 import java.util.Arrays;
     17 import java.util.HashMap;
     18 import java.util.Map;
     19 import java.util.jar.Attributes;
     20 import java.util.jar.Manifest;
     21 
     22 
     23 import sun.misc.JavaNetAccess;
     24 import sun.misc.Resource;
     25 import sun.misc.SharedSecrets;
     26 import sun.misc.URLClassPath;
     27 
     28 /**
     29  * The class loader used for loading from java.class.path.
     30  * runs in a restricted security context.
     31  */
     32 public class MyClassLoader extends URLClassLoader {
     33     public URLClassPath ucp;
     34       private Map<String, Class<?>> cache = new HashMap();
     35       private static final Method defineClassNoVerifyMethod;
     36       
     37       static String[] paths = System.getProperty("java.class.path").split(";");
     38       
     39       static URL[] urls = new URL[paths.length];
     40 
     41       static{
     42           System.out.println(Arrays.toString(paths));
     43           System.out.println(System.getProperty("java.class.path"));
     44           for(int i=0; i<urls.length; i++){
     45               try {
     46                   
     47                 urls[i] = new URL("file:"+paths[paths.length-1-i]);
     48             } catch (MalformedURLException e) {
     49                 e.printStackTrace();
     50             }
     51           }
     52           System.out.println(Arrays.toString(urls));
     53         SharedSecrets.setJavaNetAccess(new JavaNetAccess() {
     54           public URLClassPath getURLClassPath(URLClassLoader u) {
     55             return ((MyClassLoader)u).ucp;
     56           } } );
     57         Method m;
     58         try {
     59           m = SecureClassLoader.class.getDeclaredMethod(
     60             "defineClassNoVerify"new Class[] { String.class
     61             ByteBuffer.class, CodeSource.class });
     62           m.setAccessible(true);
     63         } catch (NoSuchMethodException nsme) {
     64           m = null;
     65         }
     66         defineClassNoVerifyMethod = m;
     67       }
     68       
     69       public MyClassLoader(URL[] urls) {
     70             super(MyClassLoader.urls);
     71             this.ucp = new URLClassPath(MyClassLoader.urls);
     72         }
     73       
     74       public MyClassLoader(ClassLoader parent) {
     75             super(MyClassLoader.urls, parent);
     76             this.ucp = new URLClassPath(MyClassLoader.urls);
     77         }
     78 
     79       public Class<?> loadClass(String name)
     80         throws ClassNotFoundException{
     81         Class c = null;
     82         
     83         if (name.contains("hadoop")) {
     84           c = (Class)this.cache.get(name);
     85           if (c == null) {
     86             c = findClass(name);
     87             this.cache.put(name, c);
     88           }
     89         } else {
     90           c = loadClass(name, false);
     91         }
     92         return c;
     93       }
     94 
     95       protected Class<?> findClass(String name)
     96         throws ClassNotFoundException
     97       {
     98         String path = name.replace('.''/').concat(".class");
     99         Resource res = this.ucp.getResource(path);
    100         if (res != null) {
    101           try {
    102             return defineClass(name, res, true);
    103           } catch (IOException e) {
    104             throw new ClassNotFoundException(name, e);
    105           }
    106         }
    107         throw new ClassNotFoundException(name);
    108       }
    109 
    110       private Class<?> defineClass(String name, Resource res, boolean verify) throws IOException
    111       {
    112         int i = name.lastIndexOf('.');
    113         URL url = res.getCodeSourceURL();
    114         if (i != -1) {
    115           String pkgname = name.substring(0, i);
    116 
    117           Package pkg = getPackage(pkgname);
    118           Manifest man = res.getManifest();
    119           if (pkg != null)
    120           {
    121             if (pkg.isSealed())
    122             {
    123               if (!pkg.isSealed(url)) {
    124                 throw new SecurityException(
    125                   "sealing violation: package " + pkgname + 
    126                   " is sealed");
    127               }
    128 
    129             }
    130             else if ((man != null&& (isSealed(pkgname, man))) {
    131               throw new SecurityException(
    132                 "sealing violation: can't seal package " + 
    133                 pkgname + ": already loaded");
    134             }
    135 
    136           }
    137           else if (man != null)
    138             definePackage(pkgname, man, url);
    139           else {
    140             definePackage(pkgname, nullnullnullnullnullnull
    141               null);
    142           }
    143 
    144         }
    145 
    146         ByteBuffer bb = res.getByteBuffer();
    147         byte[] bytes = bb == null ? res.getBytes() : null;
    148 
    149         CodeSigner[] signers = res.getCodeSigners();
    150         CodeSource cs = new CodeSource(url, signers);
    151 
    152         if (!verify)
    153         {
    154           Object[] args = { name, bb == null ? ByteBuffer.wrap(bytes) : bb, 
    155             cs };
    156           try {
    157             return (Class)defineClassNoVerifyMethod.invoke(this, args);
    158           }
    159           catch (IllegalAccessException localIllegalAccessException) {
    160           }
    161           catch (InvocationTargetException ite) {
    162             Throwable te = ite.getTargetException();
    163             if ((te instanceof LinkageError))
    164               throw ((LinkageError)te);
    165             if ((te instanceof RuntimeException)) {
    166               throw ((RuntimeException)te);
    167             }
    168             throw new RuntimeException("Error defining class " + name, 
    169               te);
    170           }
    171 
    172         }
    173         return defineClass(name, bytes, 0, bytes.length, cs);
    174       }
    175 
    176       private boolean isSealed(String name, Manifest man) {
    177         String path = name.replace('.''/').concat("/");
    178         Attributes attr = man.getAttributes(path);
    179         String sealed = null;
    180         if (attr != null) {
    181           sealed = attr.getValue(Attributes.Name.SEALED);
    182         }
    183         if ((sealed == null&& 
    184           ((attr = man.getMainAttributes()) != null)) {
    185           sealed = attr.getValue(Attributes.Name.SEALED);
    186         }
    187 
    188         return "true".equalsIgnoreCase(sealed);
    189       }
    190 }
    191 
    注: isSealed(), defineClass(), findClass(), 都是直接從URLClassLoader復制過來.
    代碼較粗糙, 不過意思很簡單, 就是通過把java.class.path的jar包反順序, 然后定義了自己的
    Class<?> loadClass(String name) 方法, 在加載我需要的類時在已被反序的的jar包中查找, 這樣就能首先加載我修改的類了.
    運行方法:
    java -Djava.system.class.loader=org.taobao.yuling.testClassLoader.MyClassLoader -classpath ...  MyTestClass

    Feedback

    # re: 實現自定義的classLoader加載classpath中的class[未登錄]  回復  更多評論   

    2015-01-07 14:03 by 阿帕奇
    挺不錯的。、

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 一级视频免费观看| 无码专区一va亚洲v专区在线 | 一级做a爱过程免费视| 久久精品国产亚洲αv忘忧草| 亚洲乱码中文字幕久久孕妇黑人| 成人无遮挡裸免费视频在线观看| 免费网站看av片| 又长又大又粗又硬3p免费视频| 亚洲人成www在线播放| 久久综合亚洲色HEZYO社区| 亚洲中久无码永久在线观看同| 国产成人在线免费观看| 午夜宅男在线永久免费观看网| 99国产精品免费观看视频| 中文字幕成人免费高清在线| 无忧传媒视频免费观看入口| 亚洲.国产.欧美一区二区三区| 亚洲一区二区三区四区视频| 亚洲精品无码久久毛片波多野吉衣 | 亚洲av日韩片在线观看| 免费观看的毛片手机视频| 曰批视频免费30分钟成人| 久久国产精品成人片免费| 无码成A毛片免费| 成人免费区一区二区三区| 日韩免费高清播放器| 国产在线观看免费av站| 亚洲阿v天堂在线2017免费| 免费国产a理论片| 狼人大香伊蕉国产WWW亚洲 | 免费va人成视频网站全| 国产小视频免费观看| 日产乱码一卡二卡三免费| 浮力影院第一页小视频国产在线观看免费 | 精品免费tv久久久久久久| 日本免费A级毛一片| 国产一级黄片儿免费看| 亚洲免费观看视频| 久久国产乱子伦精品免费不卡| 久9这里精品免费视频| 88xx成人永久免费观看|