Part 1. Prompt
Do I need to read this article?
Java class loaders are vital to the running of Java systems, but they are often ignored. The Java class loader finds and loads classes at runtime. The custom class loader can completely change the class loading method and personalize your Java virtual machine in your favorite way. This document briefly introduces the Java class loader and describes how to construct a custom Class Loader. This Class Loader automatically compiles code before loading the class. You will learn what the class loader is and how to create your own class loader. As long as you have some basic Java knowledge, know how to create, compile, and run a command line Java program and some basic concepts of Java class files, you can understand the content of this article. After reading this article, you should be able:
* Expand the functions of the Java Virtual Machine
* Create a custom Class Loader
* How to Integrate custom class loaders into your applications
* Modify your class loader to be compatible with Java2
Get help
If you have any questions about this article, you can contact the author Greg Travis, fuel tank: mito@panix.com.
Part 2. Introduction
What is a class loader?
Unlike other languages, Java runs on a Java Virtual Machine (JVM ). This means that the compiled code is saved in a platform-independent format, rather than running on a specific machine. This format is significantly different from the traditional executable code format. Specifically, unlike C or C ++ programs, Java programs are not an independent executable file, but composed of many separate class files. Each class file corresponds to a Java class. In addition, these class files are not immediately loaded into the memory, but loaded only when the program needs them. A Class Loader is a tool used by the Java Virtual Machine to load classes into the memory. In addition, Java class loaders are also implemented in Java. In this way, you do not need to have a deep understanding of the Java Virtual Machine to easily create your own class loader.
Why create a class loader?
Since Java virtual gold already has a class loader, do we need to create another one ourselves? Good question. The default Class Loader only knows how to load classes from the local system. When your program is fully compiled on the local machine, the default Class Loader generally works well. However, one of the most exciting aspects of Java is that it is easy to load classes from the network, not just locally.
For example, the browser can load classes through a custom class loader. There are also many ways to load classes. In addition to a simple local or network, you can also customize one of the most exciting aspects of Java:
* The digital signature is automatically verified before the untrusted code is executed.
* Decryption code based on the password provided by the user
* Dynamically create a class based on your needs
Everything you care about can be easily integrated into your application in the form of bytecode
Example of a custom Class Loader
If you have used appletviewer in JDK (Java software development kit) or other Java Embedded browsers, you have used the custom class loader. When Sun just released the Java language, one of the most exciting things was to watch how Java executes code downloaded from a remote website. It looks incredible to execute the bytecode sent from a remote site over an HTTP connection. This is because Java has the ability to install a custom class loader. The browser of a small application contains a class loader. This Class Loader accesses a remote server instead of looking for a Java class locally and loads the original bytecode file through HTTP, then, it is converted into a Java class in the Java Virtual Machine. Of course, the classloaders also do many other things: they prevent insecure Java classes and keep different small programs on different pages from interfering with each other. A package written by Luke Gorrie, Echidna, is an open Java software package that allows secure running of multiple Java applications in a Java virtual machine. It blocks interference between applications by using a custom classloader to copy class files to each application.
Examples of class loaders
We know how the Class Loader works and how to define its own class loader. Next we will create a custom Class Loader named CompilingClassLoader (CCL. CCL does compilation for us, so we don't have to compile it manually. This is basically equivalent to building a "make" program into our runtime environment. Note: Before proceeding to the next step, we need to clarify some related concepts. The system has been greatly improved in JDK 1.2 (that is, the Java 2 platform we mentioned. This article was written in JDK 1.1 and, but everything can work in later versions. ClassLoader has also been improved in Java2. The fifth part is described in detail.
Part 3. Structure of ClassLoader
Overview
The basic purpose of the classloader is to serve Java class requests. When a class is required for the Java virtual machine, a class name is assigned to the class loader, and the class loader tries to return a corresponding class instance. You can create a custom class loader by overwriting corresponding methods at different stages. Next we will understand some of the main methods of the class loader. You will understand what these methods do and how they work when loading class files. You will also know what code to write when creating a custom class loader. In the next section, you will use this knowledge to work with our custom CompilingClassLoader.
Method loadClass
ClassLoader. loadClass () is the entry point of ClassLoader. The method signature is as follows:
Class loadClass (String name, boolean resolve );
The parameter name specifies the full name (including the package name) of the class required by the java Virtual Machine, such as Foo or java. lang. Object.
The resolve parameter specifies whether the class needs to be parsed.
You can understand the parsing of classes to fully prepare for running. Resolution is generally not required. If the Java Virtual Machine only wants to know whether the class exists or whether it wants to know its parent class, parsing is completely unnecessary. In Java1.1 and earlier versions, if you want to customize the class loader, The loadClass method is the only method that needs to be overwritten in the subclass.
(ClassLoader has changed in Java1.2 and provides the findClass () method ()).
Method defineClass
DefineClass is a mysterious method in ClassLoader. This method uses a byte array to construct class instances. The original byte array containing data may come from the file system or the network. DefineClass indicates the complexity, mystery, and platform dependency of the Java Virtual Machine-It translates the bytecode into the data structure during running hours, checks the validity and so on. But you don't have to worry about it. In fact, you cannot overwrite it because the method is modified by the keyword final.
Method findSystemClass
The findSystemClass method Loads files from the local system. It searches for class files in the local system. If the class files are found, call defineClass to convert the original byte array into class objects. This is the default mechanism for loading classes by Java virtual machines when running Java applications. FindSystemClass is required only when the custom Class Loader cannot be loaded. The reason is simple: our class loader is responsible for executing some specific steps in class loading, but not for all classes. For example, even if our class loader loads some classes from a remote site, there are still many basic classes to be loaded from the local system.
These classes are not of our concern, so we let the Java Virtual Machine load them in the default way: from the local system. This is what findSystemClass does. The process is roughly as follows:
* The Java Virtual Machine requests the custom Class Loader loading class.
* Check whether the remote site has the class to be loaded.
* If yes, we get this class.
* If no, we think this is a class in the basic class library. We call findSystemClass to load it from the file system.
In most custom class loaders, you should first call findSystemClass to save time for remote searching. In fact, as we will see in the next section, it is only after we confirm that we have automatically compiled our code that the Java Virtual Machine is allowed to load classes from the local file system.
Method resolveClass
As mentioned above, Class records can be divided into partial loading (not parsing) and full loading (including parsing ). We may call resolveClass when creating a custom class loader.
Method findLoadedClass
FindLoadedClass implements a cache: When loadClass is required to load a class, you can call this method to check whether the class has been loaded to prevent a loaded class from being reloaded. This method must be called first. Let's take a look at how these methods are organized together.
In our example, loadClass is implemented to perform the following steps. (We do not specify a specific technology to obtain class files, which may be compiled from the network, from a compressed package or dynamically. In any case, we get the original bytecode file)
* Call findLoadedClass to check whether the class has been loaded.
* If it is not loaded, we can obtain the original byte array in some way.
* If the array has been obtained, call defineClass to convert it to a class object.
* If the original byte array cannot be obtained, call findSystemClass to check whether it can be obtained from the local file system.