Understand the Java Class loading principle (translation)

xiaoxiao2021-03-06  68

The first part. Tip

Do I need to read this article?

The Java class loader is critical to the operation of the Java system, but they are often ignored by us. Java class loader load

Find and load classes at runtime. Customized class loader can completely change the way the class is loaded, in the way you like.

Personalize your Java virtual machine. This article briefly introduces the Java class loader, then uses a constructed custom class loader.

Example to explain that this class loader automatically compiles the code before loading the class. What do you want to learn from the class loading?

How to create your own class loader. As long as you have some basic Java knowledge, you know how to create, compile, and transport

You can understand the content of this article in a command line Java program and some Java class files. Finish

This article, you should be able to:

* Expand the function of the Java virtual machine

* Create a custom class loader

* How to integrate custom class loaders into your application

* Modify your class loader to be compatible with Java2

Get help

There is any problem in this article, you can contact the author Greg Travis, the fuel tank: mito@panix.com.

Part II. Introduction

What is the class loader?

Different from Java and other languages, Java is running in Java Virtual Machine (JVM). This means that the compiled code is

One and platform-independent format is saved instead of running on a particular machine. This format and traditional

There are many important differences in executing code format. Specifically, different from C or C programs, Java programs are not a single

Established executable, but consisting of a lot of separate class files, each class file corresponds to a Java class. In addition, this

Some of the files are not loaded to memory immediately, but when the program needs it. The class loader is Java virtual

The machine is used to load the class into memory. Moreover, the Java class loader is also implemented with Java. This way you don't need it.

There is an in-depth understanding of Java virtual machines to easily create your own class loader.

Why create a class loader?

Since the Java virtual gold has already had a class loader, we have to create other things yourself? Default class loader

I only know how to load classes from the local system. When your program is compiled in this machine, the default class loader is generally worked.

It is very good. But one of the most exciting places in Java is very easy to load from the network without just local loading.

For example, the browser can load classes through a custom class loader. and also

Many ways to load classes. In addition to simple from the local or network, you can also be most exciting in custom Java.

One of the places:

* Automatically verify digital signatures before performing non-credit code

* Decrypt code according to the password provided by the user

* Create class according to user needs

Anything you care is convenient to integrate into your app in terms of bytecode.

Custom class loader example

If you have used AppletViewer in JDK (Java Software Development Pack) or other

Java embedded browser, you have used custom class loaders. When Sun has just released Java language, the most

A exciting thing is to watch Java how to perform code downloaded from the remote website. Execute from the remote site via HTT

P Connecting bytecode is a bit incredible. The reason why it works because Java has a custom class plus

The ability of the carrier. The small application browser contains a class loader that does not find a Java class locally, and

It is access to the remote server, load the original byte code file via HTTP, and then transform into the Java class in the Java virtual machine. when

However, the type of loader has made many things: they prevent unsafe Java classes, and keep different pages

The applet does not interfere with each other. A package echidna written by Luke Gorrie is an open Java package, he allows

A secure running multiple Java applications in a Java virtual machine. It gives each application by using a custom class loader

The copy of the sequence of a class file will prevent interference between the applications.

Our class loader example

We know how the class loader works, and we know how to define your own class loader. Next we create one

A custom class loader with a named Compiable ClassLoader (CCL). CCL is compiled for us, we will

Don't be compiled manually. This is basically equivalent to a "Make" program to build to our operating environment.

Note: We must figure out some related concepts before we carry out next step.

The system is in the JDK version 1.2 (that is, the Java 2 platform we said) has been improved. This article is in JDK1.0 and 1.1

The version is written, but all things work in later versions. ClassLoader is also improved in Java2.

The fifth part has a detailed introduction.

Part III.CLASSLOADER structure

Summary

The basic purpose of the type loader is to serve the request for the Java class. When a Java virtual machine requires a class, a class is

Name to the class loader, then the class loader attempts to return a corresponding class instance. Can be covered by different stages

The method to create a custom class loader. Next we will understand some of the main methods of the class loader. You will understand

What these methods are doing, how they work when loading a class file. You will also know to create a custom class plus

What code you need to write when the carrier. In the next section, you will use this knowledge and our custom CompilingCL

AssLoader works together.

Method LOADCLASS

ClassLoader.LoadClass () is the entry point of ClassLoader. The method is signed as follows:

Class loadClass (String name, Boolean Resolve);

Parameter Name Specifies the full name (including package name) required by the Java virtual machine, such as foo or java.lang.object.

Parameter resolve Specifies whether this class needs to be parsed

You can understand the parsing of the class as a completely prepared to run. Parrse is generally unnecessary. If Java virtual machine just want to know

Whether this class exists or wants to know its parent class, the resolution is completely unnecessary. In Java1.1 and it

Version, if you want to customize the class loader, the LoadClass method is the only way to cover over the subclass.

(ClassLoader has changed in Java1.2, providing method FindClass ()).

DEFINECLASS

DefineClass is a very mysterious way in ClassLoader. This method builds a class by one byte array.

example. This original byte array containing data may come from the file system, or it may be from the network. DefineClass table

The complexity, mystery and platform dependencies of the Java virtual machine - it converts it into runtime data by explaining the word code code

Structure, check validity, etc. But don't worry, these don't need you to do it. In fact, you can't overwrite it at all.

Because this method is modified by the keyword Final.

Method FINDSYSTEMCLASS

The FindSystemClass method loads files from the local system. It looks for class files in the local system, if found, call

DefineClass transforms the original byte array into classes. This is the default of the Java virtual machine loaded when running the Java application

mechanism. For custom class loaders, only FindsystemClass is required after we cannot load. Reason

Simple: Our class loader is responsible for performing certain steps in the load, but is not for all classes. such as,

Even if our class loader loads some classes from the remote site, there are still many basic classes to load from the local system.

These classes are not our concern, so we let Java virtual machines load them by default: from the local system. This

It is made by FindsystemClass. The entire process is approximately as follows: * Java virtual machine requests our custom class loader to load classes.

* We check if the remote site has this class that needs to be loaded.

* If there is, we get this class.

* If not, we think this is a class in the basic class library, calling FindsystemClass to load from the file system.

In most custom class loaders, you should call FindSystemClass first save time from remote lookup.

In fact, as we will see in the next part, only when we determine that we have automatically compiled our code.

Allow Java virtual machines to load classes from the local file system.

Method ResolVeclass

As mentioned above, class records can be divided into partially loaded (unresolved) and fully loaded (including parsing). We create self

When defining a class loader, you may have to call ResolVeclass.

FindlineedClass

FindloadedClass implements a cache: When you ask LoadClass to load a class, you can call this party first.

Method see if this class has been loaded and prevents re-loading a class that has been loaded. This method must be called first

Let's take a look at how these methods are organized together.

Our example implements the steps of loadClass to perform the following. (We don't specify a class file through some specific technology.

It is possible to compile from the network, from the compressed package or dynamic. In any case, we get the original byte code file)

* Call FindLoadedClass check if this class has been loaded.

* If we do not load, we get the original byte array in some way.

* If this array has been obtained, call DefineClass to transform it into a class object.

* If the original byte array cannot be obtained, call FindSystemClass to check if you can record from the local file system.

Load.

* If the parameter resolve is true, resolveclass is called to parse the class object.

* If you have not found a class yet, throw a classNotFoundException exception.

* Otherwise, return this class.

Now we have a comprehensive understanding of the application knowledge of class loaders, you can create a custom class loader. Next

Division, we will discuss CCL.

Part 4. Compiable ClassLoader

CCL show us the function of the class loader, and the purpose of the CCL is to allow our code to automatically compile and update. Below

How does it work?

* When there is a class request, first check if this class file is present on the current directory and subdirectories.

* If there is no class file, but there is a source code file, call the Java compiler to build a class file.

* If the class file already exists, check if the file is older than the source code file. If the class file is more than the source code file

Old, call the Java compiler to regenerate class files.

* If the compilation failed, or due to other reasons, it will not generate a class file from the source file, throw an exception classnotfou.

NDEXCEPTION.

* If this class has not yet been obtained, there may be other class libraries, call FindsystemClass to see if it can be found.

* If not found, throw an exception ClassNotFoundException.

* Otherwise, returns to this class.

How is Java compilation implementation?

Before we discuss, we need to figure out the Java compilation process. Usually, Java compiler is not only compiled

The classes of them are set. If the specified classes are required, it also compiles some other related classes. CCL will be one

Compiling those classes that we need to be compiled in your application. However, in general, the compiler is compiled after the first class,

CCL will find that other related classes of other needs have been compiled. why? The Java compiler uses our almost rules: if a class does not exist or the source file has been updated, it will compile this class. Java compiler basically

One step is earlier than CCL, most of the work is done by the Java compiler. We look like a CCL is compiling these classes.

In most cases, you will find it to call the compiler in the main function class, just these - simple one

It is enough to use it. However, there is a special case, these classes are not compiled when they appear. If you add according to the class name

To load a class, how to use Class.Forname, the Java compiler does not know if this class is needed. under these circumstances,

You find that the CCL calls the compiler again to compile the class. The code of the sixth part illustrates this process.

Use CompiLationClassLoader

In order to use CCL, we can't run our program directly, you must run in a special way, just like this:

% java foo arg1 arg2

We run it like this:

% Java cclrun foo arg1 arg2

CClrun is a special settle program that creates CompilingClassLoader and uses it to load our master.

Function class, this ensures that all the entire program is loaded by CompiLingClassLoader. CClrun uses JA

The VA reflects the API to call the main function of the main function class and deliver parameters to this function. Want to know more, refer to the sixth part

Source code.

Run example

We demonstrate how to work throughout the process.

The main program is a class named foo, which creates an instance of a class bar. This BAR instance creates an instance of class BAZ

The class baz exists in the package baz, which is to demonstrate how the CCL is loaded from the sub-package. Bar is also loaded based on class name BOO

This is also completed by CCL. All classes can be loaded. Use the source code from Chapter VI to execute this

program. Compile CCLRUN and COMPILINGCLASSLOADER. Make sure you don't compile other classes (Foo, Bar, Baz, A

ND boo), otherwise the CCL will not work.

% Java cclrun foo arg1 arg2

CCL: Compiable foo.java ...

Foo! arg1 arg2

Bar! arg1 arg2

Baz! arg1 arg2

CCL: Compiling Boo.java ...

Boo!

Note that the compiler is called for the first time for foo.java, and it is also compiled with Bar and Baz.baz together. Class Boo

When you need to load, the CCL once again calls the compiler to compile it.

The fifth part. Improvements to class loaders in Java2

Overview

In Java1.2 and later, the class loader has great improvements. The previous code can still work, but new

The system makes our implementation easier. This new model is the agent's entrustment model, that is, if this type of loader is not found.

To a class, it will make his parent class loader to find. The system class loader is a ancestor, system class loading of all class loaders.

Load classes by default - is also loaded from the local file system. Coverage LoadClass method generally try

Several ways to load the class, if you write a lot of class loaders, you will find that you are just once again in this complex party.

I have made some modifications in the law. Java1.2 LoadClass's default implementation contains the most common way to find classes, allowing

You override the FindClass method, and loadClass is appropriate whether the FindClass method is called. The advantage of this is that you are not

Need to override LoadClass, you only need to overwrite findclass, which can reduce workload.

New method: Findclass

This method is called by the default implementation of LoadClass. Findclass's goal is to include all class loader-specific code,

No need to repeat this code (such as calling the system class loader) when the specified method fails. New method: getSystemClassLoader

Regardless of whether you covers the method, Findclass and LoadClass, the method GetSystemClassLoader can directly access the department.

The category loader (instead of accessing indirect access by FindsystemClass).

New method: getParent

In order to delegate the request to the parent class loader, the parent class loader of this class loader can be obtained by this method. Be a custom

When the specific method in the righteous class loader cannot find a class, you may delegate the request to the parent class loader. Father of the type loader

The class loader contains code that creates this class loader.

Section 6. Source code

CompiLingClassLoader.java

The following is the contents of the file compiverclassloader.java

Import java.io. *;

/ *

CompilingClassLoader dynamically compiles the Java source file. It checks if the .class file exists, .class file is

No source file is old.

* /

Public Class CompilingClassLoader Extends ClassLoader

{

/ / Specify a file name, read the entire file content from the disk, return to the byte array.

Private Byte [] getBytes (String filename) throws oews oException {

// Get the file size.

File File = New File (filename);

Long len = file.length ();

// Creating an array just the content that can be stored.

BYTE RAW [] = new byte [(int) LEN];

// open a file

FileInputStream Fin = New FileInputStream (file);

// Read all content, if you can't read it, it indicates an error.

INT R = Fin.read (RAW);

IF (r! = len)

Throw new oException ("CAN't Read All," R "! =" LEN);

// Don't forget to turn the file.

Fin.close ();

// Return to this array.

Return RAW;

}

// Generate a process to compile the specified Java source file to develop file parameters. If the compile is successful, returns true, no,

// Return False.

Private Boolean Compile (String Javafile) throws oewception {

// Show current progress

System.out.println ("CCL: Compiable" JavaFile "...");

// Startup compiler

Process p = runtime.getime (). EXEC ("Javac" javafile;

// Waiting for compilation to end

Try {

p.WaitFor ();

} Catch (InterruptedException IE {System.out.Println (IE);}

// Check the return code to see if the compilation is wrong.

Int ret = p.exitvalue ();

// Returns to compile whether it is successful.

Return Ret == 0;

}

The core code of the // / loader - Loading the class automatically compiles the source file when needed.

Public Class LoadClass (String Name, Boolean Resolve)

Throws classnotfoundexception {

// Our goal is to get a class object.

Class clas = null; // First, check if this class is already happened.

Clas = findloadedclass (name);

//System.out.println ("FindloadedClass:" CLAS);

// Get the path name by class name, such as java.lang.object => java / lang / object

String filestub = name.replace ('.', '/');

// Build objects to source files and class files.

String javafilename = filestub "java";

String classfilename = filestub ". Class";

File javafile = new file (javaFilename);

File classfile = new file (classfilename);

//System.out.println ("j" javafail.lastmodified () "c"

// ClassFile.lastmodified ());

// First, it is judge whether it is necessary to compile. If the source file does not exist, or exist, but the source file

// Refer to the need to compile it.

IF (Javafile.exists () && (! ClassFile.exists () ||

JavaFile.lastmodified ()> classfile.lastmodified ())) {

Try {

// Compile, if the compilation failed, we must declare the cause of failure (not enough only using the old class).

IF (! COMPILE (JavaFileName) ||! ClassFile.exists ()) {

Throw new classnotfoundexception ("Compile Failed:" JavaFileName);

}

} catch (ioexception ie) {

// may compile IO errors.

Throw new classnotfoundexception (IE.toString ());

}

}

/ / Make sure we have compiled or need to be compiled, we start loading the original byte.

Try {

// Read byte.

Byte Raw [] = getBytes (ClassFileName);

// Translate into class object

Clas = defineClass (Name, Raw, 0, Raw.Length);

} catch (ioexception ie) {

// This does not mean failure, and the classes we have processed in the local class, such as java.lang.object.

}

//System.out.println ("DefineClass:" CLAS);

// May be loaded in the default manner in the class library.

IF (Clas == Null) {

Clas = FindsystemClass (Name);

}

//System.out.println ("FindsystemClass:" Clas);

// If the parameter resolve is true, the class is explained as needed.

IF (Resolve && Clas! = NULL)

ResolVeclass (Clas);

// If you haven't gotten yet, you have an error. IF (Clas == Null)

Throw New ClassNotFoundException (NAME);

/ / Otherwise, return this type of object.

Return Clas;

}

}

Ccrun.java

It is a ccrun.java file

Import java.lang.reflect. *;

/ *

CclRun runs the program with the Compiable ClassLoader.

* /

Public class cclrun

{

Static public void main (string args []) throws exception {

// The first parameter specifies the main function class to be run.

String progclass = args [0];

// The next parameter is the parameter passing to this main function class.

String progargs [] = new string [args.lendth-1];

System.Arraycopy (Args, 1, Progargs, 0, Progargs.Length);

// Create a CompiLingClassLoader

CompiableingClassLoader CCL = New CompilingClassLoader ();

// load the main function class through the CCL.

Class clas = ccl.loadClass (progclass);

// Use the reflection to call its main function and pass parameters.

// Generate a class object that represents the parameter type of the main function.

Class maingType [] = {(new string [0]). GetClass ()};

// Find the standard main function in the class.

Method main = Clas.getMethod ("main", maingtype;

// Create a list of parameters - here is a string array.

Object argsArray [] = {progargs};

// Call the main function.

Main.invoke (null, argsarray);

}

}

Foo.java

The following is the file foo.java content

Public Class Foo

{

Static public void main (string args []) throws exception {

System.out.println ("foo!" Args [0] " args [1]);

NEW BAR (Args [0], Args [1]);

}

}

Bar.java

The following is the file bar.java content

IMPORT Baz. *;

Public Class Bar

{

Public bar (string a, string b) {

System.out.println ("Bar!" A " B);

New baz (a, b);

Try {

Class Booclass = Class.Forname ("Boo");

Object boo = booclass.newinstance ();

} catch (exception e) {

E.PrintStackTrace ();

}

}

}

Baz / Baz.java

The following is file baz / baz.java content

Package baz;

Public Class Baz

{

Public Baz (String a, string b) {

System.out.println ("BAZ!" A " B);

}

}

Boo.java

The following is the fileboo.java content public class boo

{

Public boo () {

System.out.println ("BOO!");

}

}

Part 7. Summary

to sum up

By this article you realize that creating a custom class loader allows you to go deep into the Java virtual machine. You can

Any resource loaded file, or dynamically generate it so you can do much more you can do by extending these features.

Things, you can complete some powerful features.

Other topics about ClassLoader

Just as the beginning of this article, the custom class loader plays an important role in the Java embedded browser and the applet browser.

effect. The other features of the class loader are given below.

* Security: Customized class loader can check if it has the correct number before handing this class to the Java virtual machine

signature. You can also create a "sandbox" to prevent call to certain methods, which is to block the source code

This class is implemented in the operation other than the sandbox.

* Encryption: You can dynamically decode through the custom class loader, all your class files cannot be viewed by anti-compilation

Code. The user needs a password to run the program, which is used to decrypt the code.

* Archive: Do you need to release your code in some format or compression? Custom ClassLoader

Generate a band code file from any of the resources you want.

* Self-extract: You can compile the entire application into an executable class file, this file includes compression or

Data encrypted, there is an internal product loader, when the program is running, he is unproved to memory - no need

Before install.

* Dynamically generated: You can generate those categories that are referenced - the categories you need to use can be generated and then

Give the Java virtual machine.

转载请注明原文地址:https://www.9cbs.com/read-120180.html

New Post(0)