沉睡森林@漂在北京

          本處文章除注明“轉載”外均為原創,轉載請注明出處。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            152 隨筆 :: 4 文章 :: 114 評論 :: 0 Trackbacks
          The JarClassLoader Class
          The JarClassLoader class extends java.net.URLClassLoader. As its name implies, URLClassLoader is designed to be used for loading classes and resources that are accessed by searching a set of URLs. The URLs can refer either to directories or to JAR files.

          In addition to subclassing URLClassLoaderJarClassLoader also makes use of features in two other new JAR-related APIs, the java.util.jarpackage and the java.net.JarURLConnection class. In this section, we'll look in detail at the constructor and two methods ofJarClassLoader.

          The JarClassLoader Constructor

          The constructor takes an instance of java.net.URL as an argument. The URL passed to this constructor will be used elsewhere inJarClassLoader to find the JAR file from which classes are to be loaded.
          public JarClassLoader(URL url) {
          super(new URL[] { url });
          this.url = url;
          }
          
          The URL object is passed to the constructor of the superclass, URLClassLoader, which takes a URL[] array, rather than a single URLinstance, as an argument.

          The getMainClassName Method

          Once a JarClassLoader object is constructed with the URL of a JAR-bundled application, it's going to need a way to determine which class in the JAR file is the application's entry point. That's the job of the getMainClassName method:
          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;
          }
          
          You may recall from a previous lesson that a JAR-bundled application's entry point is specified by the Main-Class header of the JAR file's manifest. To understand how getMainClassName accesses the Main-Class header value, let's look at the method in detail, paying special attention to the new JAR-handling features that it uses:

          The JarURLConnection class and JAR URLs

          The getMainClassName method uses the JAR URL format specified by the java.net.JarURLConnection class. The syntax for the URL of a JAR file is as in this example:
          jar:http://www.xxx.yyy/jarfile.jar!/
          
          The terminating !/ separator indicates that the URL refers to an entire JAR file. Anything following the separator refers to specific JAR-file contents, as in this example:
          jar:http://www.xxx.yyy/jarfile.jar!/mypackage/myclass.class
          

          The first line in the getMainClassName method is:

          URL u = new URL("jar", "", url + "!/");
          
          This statement constructs a new URL object representing a JAR URL, appending the !/ separator to the URL that was used in creating theJarClassLoader instance.

          The java.net.JarURLConnection class

          This class represents a communications link between an application and a JAR file. It has methods for accessing the JAR file's manifest. The second line of getMainClassName is:
          JarURLConnection uc = (JarURLConnection)u.openConnection();
          
          In this statement, URL instance created in the first line opens a URLConnection. The URLConnection instance is then cast to JarURLConnectionso it can take advantage of JarURLConnection's JAR-handling features.

          Fetching Manifest Attributes: java.util.jar.Attributes

          With a JarURLConnection open to a JAR file, you can access the header information in the JAR file's manifest by using thegetMainAttributes method of JarURLConnection. This method returns an instance of java.util.jar.Attributes, a class that maps header names in JAR-file manifests with their associated string values. The third line in getMainClassName creates an Attributes object:
          Attributes attr = uc.getMainAttributes();
          

          To get the value of the manifest's Main-Class header, the fourth line of getMainClassName invokes the Attributes.getValue method:

          return attr != null
          ? attr.getValue(Attributes.Name.MAIN_CLASS)
          : null;
          
          The method's argument, Attributes.Name.MAIN_CLASS, specifies that it's the value of the Main-Class header that you want. (The Attributes.Nameclass also provides static fields such as MANIFEST_VERSIONCLASS_PATH, and SEALED for specifying other standard manifest headers.)

          The invokeClass Method

          We've seen how JarURLClassLoader can identify the main class in a JAR-bundled application. The last method to consider,JarURLClassLoader.invokeClass, enables that main class to be invoked to launch the JAR-bundled application:
          public void invokeClass(String name, String[] args)
          throws ClassNotFoundException,
          NoSuchMethodException,
          InvocationTargetException
          {
          Class c = 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
          }
          }
          

          The invokeClass method takes two arguments: the name of the application's entry-point class and an array of string arguments to pass to the entry-point class's main method. First, the main class is loaded:

          Class c = loadClass(name);
          
          The loadClass method is inherited from java.lang.ClassLoader.

          Once the main class is loaded, the reflection API of the java.lang.reflect package is used to pass the arguments to the class and launch it. You can refer to the tutorial on The Reflection API for a review of reflection.

          posted on 2010-06-01 23:50 王總兵 閱讀(396) 評論(0)  編輯  收藏 所屬分類: Other
          主站蜘蛛池模板: 崇明县| 扎赉特旗| 宝应县| 安康市| 筠连县| 新余市| 新龙县| 景东| 云和县| 金沙县| 吴堡县| 东乌珠穆沁旗| 金乡县| 金寨县| 望奎县| 和龙市| 仙游县| 尚志市| 襄垣县| 陇西县| 凤翔县| 武冈市| 庐江县| 高邑县| 万山特区| 宜兴市| 五原县| 封开县| 资溪县| 城步| 宜春市| 平武县| 江孜县| 嘉义市| 开化县| 凤阳县| 莱阳市| 宝丰县| 襄城县| 定西市| 富宁县|