Java load all class in jar

ClassLoader in Java

The Java ClassLoader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine. The Java run time system does not need to know about files and file systems because of classloaders. Java classes aren’t loaded into memory all at once, but when required by an application. At this point, the Java ClassLoader is called by the JRE and these ClassLoaders load classes into memory dynamically.

Types of ClassLoaders in Java

Not all classes are loaded by a single ClassLoader. Depending on the type of class and the path of class, the ClassLoader that loads that particular class is decided. To know the ClassLoader that loads a class the getClassLoader() method is used. All classes are loaded based on their names and if any of these classes are not found then it returns a NoClassDefFoundError or ClassNotFoundException. A Java Classloader is of three types:

  1. BootStrap ClassLoader: A Bootstrap Classloader is a Machine code which kickstarts the operation when the JVM calls it. It is not a java class. Its job is to load the first pure Java ClassLoader. Bootstrap ClassLoader loads classes from the location rt.jar. Bootstrap ClassLoader doesn’t have any parent ClassLoaders. It is also called as the Primordial ClassLoader.
  2. Extension ClassLoader: The Extension ClassLoader is a child of Bootstrap ClassLoader and loads the extensions of core java classes from the respective JDK Extension library. It loads files from jre/lib/ext directory or any other directory pointed by the system property java.ext.dirs.
  3. System ClassLoader: An Application ClassLoader is also known as a System ClassLoader. It loads the Application type classes found in the environment variable CLASSPATH, -classpath or -cp command line option. The Application ClassLoader is a child class of Extension ClassLoader.

Note: The ClassLoader Delegation Hierarchy Model always functions in the order Application ClassLoader->Extension ClassLoader->Bootstrap ClassLoader. The Bootstrap ClassLoader is always given the higher priority, next is Extension ClassLoader and then Application ClassLoader.

Principles of functionality of a Java ClassLoader

Principles of functionality are the set of rules or features on which a Java ClassLoader works. There are three principles of functionality, they are:

  1. Delegation Model: The Java Virtual Machine and the Java ClassLoader use an algorithm called the Delegation Hierarchy Algorithm to Load the classes into the Java file. The ClassLoader works based on a set of operations given by the delegation model. They are:
    • ClassLoader always follows the Delegation Hierarchy Principle.
    • Whenever JVM comes across a class, it checks whether that class is already loaded or not.
    • If the Class is already loaded in the method area then the JVM proceeds with execution.
    • If the class is not present in the method area then the JVM asks the Java ClassLoader Sub-System to load that particular class, then ClassLoader sub-system hands over the control to Application ClassLoader.
    • Application ClassLoader then delegates the request to Extension ClassLoader and the Extension ClassLoader in turn delegates the request to Bootstrap ClassLoader.
    • Bootstrap ClassLoader will search in the Bootstrap classpath(JDK/JRE/LIB). If the class is available then it is loaded, if not the request is delegated to Extension ClassLoader.
    • Extension ClassLoader searches for the class in the Extension Classpath(JDK/JRE/LIB/EXT). If the class is available then it is loaded, if not the request is delegated to the Application ClassLoader.
    • Application ClassLoader searches for the class in the Application Classpath. If the class is available then it is loaded, if not then a ClassNotFoundException exception is generated.
  2. Visibility Principle: The Visibility Principle states that a class loaded by a parent ClassLoader is visible to the child ClassLoaders but a class loaded by a child ClassLoader is not visible to the parent ClassLoaders. Suppose a class GEEKS.class has been loaded by the Extension ClassLoader, then that class is only visible to the Extension ClassLoader and Application ClassLoader but not to the Bootstrap ClassLoader. If that class is again tried to load using Bootstrap ClassLoader it gives an exception java.lang.ClassNotFoundException.
  3. Uniqueness Property: The Uniqueness Property ensures that the classes are unique and there is no repetition of classes. This also ensures that the classes loaded by parent classloaders are not loaded by the child classloaders. If the parent class loader isn’t able to find the class, only then the current instance would attempt to do so itself.
Читайте также:  Netvirusu net nod32trial html

Methods of Java.lang.ClassLoader

After the JVM requests for the class, a few steps are to be followed in order to load a class. The Classes are loaded as per the delegation model but there are a few important Methods or Functions that play a vital role in loading a Class.

  1. loadClass(String name, boolean resolve): This method is used to load the classes which are referenced by the JVM. It takes the name of the class as a parameter. This is of type loadClass(String, boolean).
  2. defineClass(): The defineClass() method is a final method and cannot be overridden. This method is used to define a array of bytes as an instance of class. If the class is invalid then it throws ClassFormatError.
  3. findClass(String name): This method is used to find a specified class. This method only finds but doesn’t load the class.
  4. findLoadedClass(String name): This method is used to verify whether the Class referenced by the JVM was previously loaded or not.
  5. Class.forName(String name, boolean initialize, ClassLoader loader): This method is used to load the class as well as initialize the class. This method also gives the option to choose any one of the ClassLoaders. If the ClassLoader parameter is NULL then Bootstrap ClassLoader is used.

Example: The following code is executed before a class is loaded:

Источник

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.jar package and the java.net.JarURLConnection class. In this section, we’ll look in detail at the constructor and two methods of JarClassLoader.

Читайте также:  Создать массив из массива java

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 in JarClassLoader 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 URL instance, 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.example.com/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.example.com/jarfile.jar!/mypackage/myclass.class

The first line in the getMainClassName method is:

Читайте также:  Установить пакет php mysql

This statement constructs a new URL object representing a JAR URL, appending the !/ separator to the URL that was used in creating the JarClassLoader 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 JarURLConnection so 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 the getMainAttributes 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.Name class 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:

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.

Источник

Оцените статью