The JarClassLoader Class

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 URLClassLoader, JarClassLoader 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_VERSION, CLASS_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.

本文转自博客园沉睡森林@漂在北京的博客,原文链接:The JarClassLoader Class,如需转载请自行联系原博主。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值