<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java究竟怎么玩?

      天地程序已定棋,人間大數(shù)待變局

        博客園  :: 首頁  :: 新隨筆  :: 聯(lián)系 :: 訂閱 訂閱  :: 管理

      我們大家都知道,每個運行中的線程都有一個成員contextClassLoader,用來在運行時動態(tài)地載入其它類。

      系統(tǒng)默認的contextClassLoader是systemClassLoader,所以一般而言java程序在執(zhí)行時可以使用JVM自帶的類、$JAVA_HOME/jre/lib/ext/中的類和$CLASSPATH/中的類,對于非默認的jar,一般只能手動在配置環(huán)境添加。

      但事實上,我們可以通過Thread.currentThread().setContextClassLoader()更改當前線程的contextClassLoader行為,實現(xiàn)在程序內(nèi)加載外部jar。

      PS:
      ClassLoader的工作原理是:
      1) 線程需要用到某個類時,contextClassLoader將被請求來載入該類
      2) contextClassLoader請求它的父ClassLoader來完成該載入請求
      3) 如果父ClassLoader無法載入類,則contextClassLoader試圖自己來載入



      package org.loon.framework.jar;

      /**
       * <p>Title: LoonFramework</p>
       * <p>Description:JarLoader,用于jar包的外部操作</p>
       * <p>Copyright: Copyright (c) 2007</p>
       * <p>Company: LoonFramework</p>
       * 
      @author chenpeng  
       * @email:ceponline@yahoo.com.cn 
       * 
      @version 0.1
       
      */

      import java.io.BufferedInputStream;
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.InputStream;
      import java.lang.reflect.Method;
      import java.net.MalformedURLException;
      import java.net.URL;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.Hashtable;
      import java.util.jar.JarEntry;
      import java.util.jar.JarInputStream;
      import java.util.jar.Manifest;

      public class JarLoader extends ClassLoader {
          
      //資源緩存
          public static Hashtable resources = new Hashtable();
       
          
      public static JarLoader loader = new JarLoader();

          
      public static Class load(byte[] resource) throws Exception {
              
      // 主函數(shù)所在類全稱
              String mainClassName = "";
              
      //class資源及實體緩存
              ArrayList classNames = new ArrayList();
              ArrayList classBuffers 
      = new ArrayList();
              
      // 存儲依賴類
              HashMap depends = new HashMap();
              
      // 將byte[]轉(zhuǎn)為JarInputStream
              JarInputStream jar = new JarInputStream(new ByteArrayInputStream(
                      resource));
              Manifest manifest 
      = jar.getManifest();
              
      // 當Main-Class被聲明時,獲得主函數(shù)所在類全稱
              if (manifest != null{
                  mainClassName 
      = manifest.getMainAttributes().getValue("Main-Class");
              }

              
      // 依次獲得對應(yīng)JAR文件中封裝的各個被壓縮文件的JarEntry
              JarEntry entry;
              
      while ((entry = jar.getNextJarEntry()) != null{
                  
      // 當找到的entry為class時
                  if (entry.getName().toLowerCase().endsWith(".class")) {
                      
      // 將類路徑轉(zhuǎn)變?yōu)轭惾Q
                      String name = entry.getName().substring(0,
                              entry.getName().length() 
      - ".class".length()).replace(
                              
      '/''.');
                      
      // 加載該類
                      byte[] data = getResourceData(jar);
                      
      // 緩存類名及數(shù)據(jù)
                      classNames.add(name);
                      classBuffers.add(data);

                  }
       else {
                      
      // 非class結(jié)尾但開頭字符為'/'時
                      if (entry.getName().charAt(0== '/'{
                          resources.put(entry.getName(), getResourceData(jar));
                      
      // 否則追加'/'后緩存    
                      }
       else {
                          resources.put(
      "/" + entry.getName(), getResourceData(jar));
                      }

                  }

              }

              
      //當獲得的main-class名不為空時
              while (classNames.size() > 0{
                  
      //獲得類路徑全長
                  int n = classNames.size();
                  
      for (int i = classNames.size() - 1; i >= 0; i--{
                      
      try {
                          
      //查詢指定類
                          loader.defineClass((String) classNames.get(i),
                                  (
      byte[]) classBuffers.get(i), 0,
                                  ((
      byte[]) classBuffers.get(i)).length);
                          
      //獲得類名
                          String pkName = (String) classNames.get(i);
                          
      if (pkName.lastIndexOf('.'>= 0{
                              pkName 
      = pkName
                                      .substring(
      0, pkName.lastIndexOf('.'));
                              
      if (loader.getPackage(pkName) == null{
                                  loader.definePackage(pkName, 
      nullnullnull,
                                          
      nullnullnullnull);
                              }

                          }

                          
      //查詢后刪除緩沖
                          classNames.remove(i);
                          classBuffers.remove(i);
                      }
       catch (NoClassDefFoundError e) {
                          depends.put((String) classNames.get(i), e.getMessage()
                                  .replaceAll(
      "/""."));
                      }
       catch (UnsupportedClassVersionError e) {
                          
      //jre版本錯誤提示
                          throw new UnsupportedClassVersionError(classNames.get(i)
                                  
      + "" + System.getProperty("java.vm.name"+ " "
                                  
      + System.getProperty("java.vm.version"+ ")");
                      }

                  }

                  
      if (n == classNames.size()) {
                      
      for (int i = 0; i < classNames.size(); i++{
                          System.err.println(
      "NoClassDefFoundError:"
                                  
      + classNames.get(i));
                          String className 
      = (String) classNames.get(i);
                          
      while (depends.containsKey(className)) {
                              className 
      = (String) depends.get(className);
                          }

                      }

                      
      break;
                  }

              }

              
      try {
                  
      //加載
                  Thread.currentThread().setContextClassLoader(loader);
                  
      // 獲得指定類,查找其他類方式相仿
                  return Class.forName(mainClassName, true, loader);
              }
       catch (ClassNotFoundException e) {
                  String className 
      = mainClassName;
                  
      while (depends.containsKey(className)) {
                      className 
      = (String) depends.get(className);
                  }

                  
      throw new ClassNotFoundException(className);
              }

          }


          
      /**
           * 獲得指定路徑文件的byte[]形式
           * 
      @param name
           * 
      @return
           
      */

          
      final static public byte[] getDataSource(String name) {
              FileInputStream fileInput;
              
      try {
                  fileInput 
      = new FileInputStream(new File(name));
              }
       catch (FileNotFoundException e) {
                  fileInput 
      = null;
              }

              BufferedInputStream bufferedInput 
      = new BufferedInputStream(fileInput);
              
      return getDataSource(bufferedInput);
          }

          
          
      /**
           * 獲得指定InputStream的byte[]形式
           * 
      @param name
           * 
      @return
           
      */

          
      final static public byte[] getDataSource(InputStream is) {
              
      if (is == null{
                  
      return null;
              }

              ByteArrayOutputStream byteArrayOutputStream 
      = new ByteArrayOutputStream();
              
      byte[] arrayByte = null;
              
      try {
                  
      byte[] bytes = new byte[8192];
                  bytes 
      = new byte[is.available()];
                  
      int read;
                  
      while ((read = is.read(bytes)) >= 0{
                      byteArrayOutputStream.write(bytes, 
      0, read);
                  }

                  arrayByte 
      = byteArrayOutputStream.toByteArray();
              }
       catch (IOException e) {
                  
      return null;
              }
       finally {
                  
      try {
                      
      if (byteArrayOutputStream != null{
                          byteArrayOutputStream.close();
                          byteArrayOutputStream 
      = null;
                      }

                      
      if (is != null{
                          is.close();
                          is 
      = null;
                      }


                  }
       catch (IOException e) {
                  }

              }

              
      return arrayByte;
          }


          
      /**
           * 獲得指定JarInputStream的byte[]形式
           * 
      @param jar
           * 
      @return
           * 
      @throws IOException
           
      */

           
      final static private byte[] getResourceData(JarInputStream jar)
                  
      throws IOException {
              ByteArrayOutputStream data 
      = new ByteArrayOutputStream();
              
      byte[] buffer = new byte[8192];
              
      int size;
              
      while (jar.available() > 0{
                  size 
      = jar.read(buffer);
                  
      if (size > 0{
                      data.write(buffer, 
      0, size);
                  }

              }

              
      return data.toByteArray();
          }


           
      /**
            * 重載的getResource,檢查是否重復(fù)包含
            
      */

          
      public URL getResource(String name) {
              
      if (resources.containsKey("/" + name)) {
                  
      try {
                      
      return new URL("file:///" + name);
                  }
       catch (MalformedURLException e) {
                      e.printStackTrace();
                  }

              }

              
      return super.getResource(name);
          }


          
      /**
           * 執(zhí)行指定class類
           * 
      @param clz
           * 
      @param methodName
           * 
      @param args
           
      */

          
      public static void callVoidMethod(Class clz, String methodName,
                  String[] args) 
      {
              Class[] arg 
      = new Class[1];
              arg[
      0= args.getClass();
              
      try {
                  Method method 
      = clz.getMethod(methodName, arg);
                  Object[] inArg 
      = new Object[1];
                  inArg[
      0= args;
                  method.invoke(clz, inArg);
              }
       catch (Exception e) {
                  System.err.println(e.getMessage());
              }

          }

          
           
      /**
            * 重載的getResourceAsStream,檢查是否重復(fù)包含
            
      */

          
      public InputStream getResourceAsStream(String name) {
              
      if (name.charAt(0== '/'{
                  name 
      = name.substring(1);
              }

              
      if (resources.containsKey("/" + name)) {
                  
      return new ByteArrayInputStream((byte[]) resources.get("/" + name));
              }

              
      return super.getResourceAsStream(name);
          }


      }


      運行示例:

      package org.loon.framework.jar;


      /**
       * <p>
       * Title: LoonFramework
       * </p>
       * <p>
       * Description:從外部啟動jar包
       * </p>
       * <p>
       * Copyright: Copyright (c) 2007
       * </p>
       * <p>
       * Company: LoonFramework
       * </p>
       * 
       * 
      @author chenpeng
       * @email:ceponline@yahoo.com.cn
       * 
      @version 0.1
       
      */

      public class JarTest {

          
      public static void main(String[] args) {
              
      //將jar包轉(zhuǎn)為byte[]
              byte[] resource = JarLoader.getDataSource("D:/fps_test.jar");
              
      try {
                  
      //通過byte[]獲得主函數(shù)所在類
                  Class clz = JarLoader.load(resource);
                  
      //調(diào)用main函數(shù)
                  JarLoader.callVoidMethod(clz, "main"new String[] {""});
              }
       catch (Exception e) {
                  e.getStackTrace();
              }


          }


      }


      這時即使指定jar包沒有被我們添加到lib中,程序依舊被順利啟動了。

      但是有個缺點,在沒有優(yōu)化的前提下,這種直接加載外部包的速度在jvm會有很大損耗。

      我們可以看到,fps值降低到正常值的50%左右(此fps實例見我CSDN以前的文章),所以并不適合直接運用在需要復(fù)雜運算的jar中類調(diào)用上(當然,有興趣的話,可以在代碼中優(yōu)化,我自己在項目中寫的另一個例子速度明顯比這個快)。但是對于運算量小的外部jar調(diào)用,還是很方便的。
      posted on 2007-11-12 15:38  cping  閱讀(1018)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本精品不卡一二三区| 伊人久久大香线蕉网av| 久久一级黄色大片免费观看 | 天天做天天爱夜夜爽导航| 18成人片黄网站www| 亚洲中文字幕精品一区二区三区 | 熟妇人妻无码中文字幕老熟妇| 成人午夜大片免费看爽爽爽| 国产精品99一区二区三区| 国产大陆av一区二区三区| 国产性色的免费视频网站| 国产成人卡2卡3卡4乱码| 国产在线播放专区av| 老司机精品成人无码AV| 成年女人片免费视频播放A| 18禁黄网站禁片免费观看| 成人免费乱码大片a毛片| 久久久久人妻一区精品色 | 亚洲永久视频| 欧美大香线蕉线伊人久久| 久久久久青草线蕉综合超碰| 日韩精品一区二区高清视频| 日韩中文免费一区二区| 亚洲精品漫画一二三区| 国产成人高清亚洲一区二区| 欧美成人精品三级在线观看| 国产精品午夜福利合集| 亚洲欧美精品一中文字幕| 久久久久国产一级毛片高清版A| 日区中文字幕一区二区| 亚洲成a人片在线观看中文| 亚洲一区二区不卡av| 无码抽搐高潮喷水流白浆| 亚洲精品无码日韩国产不卡av| 视频一区视频二区视频三 | 加勒比无码人妻东京热| 少妇午夜啪爽嗷嗷叫视频| 久热久精久品这里在线观看| 亚洲精品美女一区二区| 国产精品美女www爽爽爽视频| 襄城县|