Learn more about JAVAclassloader-general Linux technology-Linux programming and kernel. Unlike a program written in C or C ++, a Java program is not an executable file, but composed of many independent class files. Each file corresponds to a Java class.
In addition, these class files are not immediately loaded into the memory, but the memory is loaded according to the program's needs. ClassLoader is the part of the JVM that loads classes into the memory.
Moreover, Java ClassLoader is written in Java. This means that it is very easy to create your own ClassLoader without having to understand the minor details of JVM.
Why write ClassLoader?
If the JVM already has a ClassLoader, why write another one? Good question. The default ClassLoader only knows how to mount class files from the local file system. However, this is only suitable for general cases, that is, the Java program has been fully compiled and the computer is in the waiting state.
But the most innovative thing about Java is that JVM can easily retrieve classes from non-local hard disks or from the network. For example, a browser can use a custom ClassLoader to load executable content from a Web site.
There are many other ways to obtain class files. In addition to simply loading files from a local or network, you can use a custom ClassLoader to complete the following tasks:
Automatically verifies the digital signature before executing the untrusted code
Use the password provided by the user to transparently decrypt the code
Dynamically create custom build classes that meet specific user needs
Any content that you think can generate a Java bytecode can be integrated into the application.
Custom ClassLoader example
If you have used JDK or any Applet viewer based on a Java browser, you must have used a custom ClassLoader.
One of the most exciting things about Sun's first release of the Java language was watching how the new technology executes code loaded from a remote Web server at runtime. (In addition, there is even more exciting thing-the Java technology provides a powerful language that facilitates code writing .) What's even more exciting is that it can execute bytecode sent from a remote Web server over an HTTP connection.
This feature is attributed to the ability to install custom ClassLoader in Java. The Applet viewer contains a ClassLoader, which does not look for classes in the local file system. Instead, it accesses the Web site on the remote server and loads the original bytecode file through HTTP, and convert them into classes in JVM.
ClassLoaders in browsers and Applet viewers can also do other things: they support security and enable different applets to run on different pages without interfering with each other.
The Echidna written by Luke Gorrie is an open source package that enables you to run multiple Java applications on a single virtual machine. It uses a custom ClassLoader to provide each application with its own copy of such files to prevent mutual interference between applications.
ClassLoader example
After learning how ClassLoader works and how to write ClassLoader, we will create a Classloader called CompilingClassLoader (CCL. CCL compiles Java code for us without interfering with this process. It is basically similar to the "make" program directly built into the runtime system.
Note: before learning more, you should note that some aspects of the ClassLoader System (Java 2 platform) have been improved in JDK 1.2 ). This tutorial is based on JDK 1.0 and 1.1, but it can also be run in a later version.
ClassLoader changes in Java 2 describe the changes in Java version 1.2 and provide detailed information for modifying ClassLoader to take advantage of these changes.
The basic goal of ClassLoader is to provide services for class requests. When the JVM needs to use a Class, it requests this Class from ClassLoader according to the name, and then ClassLoader tries to return a Class object that represents this Class. You can create a custom ClassLoader by overwriting methods corresponding to different stages of the process.
In the rest of this article, you will learn the key methods of Java ClassLoader. You will understand the role of each method and how it fits into the process of loading class files. You will also know what code you need to write when creating your ClassLoader.
In the following section, you will use this knowledge to use CompilingClassLoader, The ClassLoader example.
Method loadClass
ClassLoader. loadClass () is the entry point of ClassLoader. The features are as follows:
Class loadClass (String name, boolean resolve );
The name parameter specifies the name of the class required by JVM, which is expressed in package notation, such as Foo or java. lang. Object. The resolve parameter indicates whether the method needs to parse the class. Before preparing the execution class, consider class resolution. Resolution is not always required. If the JVM only needs to know whether the class exists or find out the super class of the class, it does not need to be parsed.
In Java 1.1 and earlier versions, the loadClass method is the only method to override when creating a custom ClassLoader. (ClassLoader changes in Java 2 provide information about the findClass () method in Java 1.2 .)
Method defineClass
The defineClass method is the main tool of ClassLoader. This method accepts an array composed of the original bytes and converts it to a Class object. The original array contains data loaded from a file system or network.
DefineClass manages many of the complex, mysterious, and implementation-dependent aspects of JVM-It analyzes bytecode into runtime data structures, verifies validity, and so on. Don't worry, you don't need to write it yourself. In fact, even if you want to do so, you cannot overwrite it because it has been marked as final.
Method findSystemClass
The findSystemClass method Loads files from the local file system. It looks for a Class file in the local file system. If it exists, it will use defineClass to convert the original byte to a Class object to convert the file to a Class. When running a Java application, this is the default mechanism for JVM to load classes normally. (ClassLoader changes in Java 2 provide detailed information about the process changes in Java 1.2 .)
For a custom ClassLoader, you can use findSystemClass only after you try other methods to load the class. The reason is simple: ClassLoader is responsible for executing the special steps for loading classes, not for all classes. For example, even if the ClassLoader loads some classes from a remote Web site, a large number of basic Java libraries need to be installed on the local machine. These classes are not of our concern, so JVM should load them by default: from the local file system. This is the use of findSystemClass.
The workflow is as follows:
Request a custom ClassLoader to load the class.
Check the remote Web site to see if any classes are required.
If yes, It is better. capture this class to complete the task.
If no, if this class is in the Basic Java library, call findSystemClass to load the class from the file system.
In most custom ClassLoaders, The findSystemClass is called first to save the time it takes to search for many Java library classes that can be loaded locally. However, as we can see in the next section, JVM loads classes from the local file system until we are sure that our application code can be automatically compiled.
Method resolveClass
As mentioned above, classes can be loaded not completely (without resolution), or completely (with resolution. When writing our own loadClass, you can call resolveClass, depending on the resolve parameter value of loadClass.
Method findLoadedClass
FindLoadedClass acts as a cache: When loadClass is requested to load the class, it calls this method to check whether the class has been loaded, which can avoid the trouble of re-loading the existing class. Call this method first.
Assembly
Let's take a look at how to assemble all the methods.
The following is an example of loadClass implementation. (Here, we do not specify the technology used to generate class files-it can be installed from Net, extracted from archive files, or compiled in real time. No matter which one, it is a special magic way that we get the bytes of the original class file .)
CCL decryption
Our ClassLoader (CCL) task is to ensure that the Code is compiled and updated.
The following describes how it works:
When requesting a category, first check whether it is in the current directory or corresponding subdirectory of the disk.
If the class does not exist, but the source code does, the Java compiler is called to generate class files.
If the class already exists, check whether it is older than the source code. If yes, call the Java compiler to regenerate class files.
If the compilation fails or the class file cannot be generated from the existing source code for other reasons, ClassNotFoundException is returned.
If the class still does not exist, it may be in other libraries, so we call findSystemClass to find the class.
If no, ClassNotFoundException is returned.
Otherwise, the class is returned.
Call findLoadedClass to check whether a mounted class exists.
If not, use the special magic method to obtain the original bytes.
If the original bytes exist, call defineClass to convert them into Class objects.
If no original bytes exist, call findSystemClass to check whether the class is obtained from the local file system.
If the resolve parameter is true, call resolveClass to parse the Class object.
If no class exists, ClassNotFoundException is returned.
Otherwise, return the class to the caller.
How Java compilation works
Before further discussion, we should take a step back to discuss Java compilation. Generally, the Java compiler does not just compile the class you require it to compile. It also compiles other classes if these classes are required by the classes you want to compile.
CCL compiles each class in the application one by one. But in general, after the compiler finishes compiling the first class, CCL will find all the classes to be compiled and then compile it. Why? The Java compiler is similar to the rule we are using: if the class does not exist or is older than its source code, it needs to be compiled. In fact, the Java compiler does most of the work before CCL.
When CCL compiles them, it reports the classes on the application it is compiling. In most cases, CCL will call the compiler on the main class of the program, and it will finish all the work to be done-a single call to the compiler is enough.
However, some classes are not compiled in the first step. If you use the Class. forName method to load classes by name, the Java compiler will not know what this Class requires. In this case, you will see that CCL runs the Java compiler again to compile this class. This process is demonstrated in the source code.
Use CompilationClassLoader
To use CCL, you must call the program in a special way. You cannot directly run this program, for example, % java Foo arg1 arg2.
Run it as follows:
% Java CCLRun Foo arg1 arg2
CCLRun is a special stub program. It creates CompilingClassLoader and uses it to load the main class of the program to ensure that the entire program is loaded through CompilingClassLoader. CCLRun uses the Java Reflection API to call the main method of a specific class and pass the parameter to it. For more information, see source code.
Running example
The source code includes a group of small classes, which demonstrate the working method. The main program is the Foo class, which creates an instance of the class Bar. Class Bar creates an instance of another Class Baz in the baz package to show how CCL handles the code in the sub-package. Bar is also loaded by name, and its name is Boo, which is used to show that it can also work with CCL.
Each class declares that it has been loaded and run. Use the source code to try it out. Compile CCLRun and CompilingClassLoader. Make sure that you do not compile other classes (Foo, Bar, Baz, and Boo). Otherwise, CCL will not be used because these classes have already been compiled.
% Java CCLRun Foo arg1 arg2
CCL: Compiling Foo. java...
Foo! Arg1 arg2
Bar! Arg1 arg2
Baz! Arg1 arg2
CCL: Compiling Boo. java...
Boo!
Note: first, call the compiler, Foo. java to manage Bar and baz. Baz. It is called until Bar loads Boo by name, then CCL will call the compiler again to compile it.
CompilingClassLoader. java
The source code of CompilingClassLoader. java is as follows:
// $ Id $
Import java. io .*;
/*
A CompilingClassLoader compiles your Java source on-the-fly. It checks
For nonexistent. class files, or. class files that are older than their
Corresponding source code.
*/
Public class CompilingClassLoader extends ClassLoader
{
// Given a filename, read the entirety of that file from disk
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.