Class Loading --- (class load mechanism, the story of developers have to know) - Next

xiaoxiao2021-03-06  39

How to construct a custom ClassLoader Since the custom ClassLoader can solve the above problem, then take a look, how we use custom ClassLoader.

Combined with the original code of this variety - (in DifferentVersionsPush's directory), there is a FileSystemClassLoader, the class diagram is described below:

Figure 9.

Look at his method FindclassBytes (String classname);

public byte [] findClassBytes (String className) {try {String pathName = currentRoot File.separatorChar className replace (, File.separatorChar '.') ".class";. FileInputStream inFile = new FileInputStream (pathName); byte [ ] classBytes = new byte [inFile.available ()]; inFile.read (classBytes); return classBytes;} catch (java.io.IOException ioEx) {return null;}} public Class findClass (String name) throws ClassNotFoundException {byte [] classBytes = findClassBytes (name); if (classBytes == null) {throw new ClassNotFoundException ();} else {return defineClass (name, classBytes, 0, classBytes.length);}} public Class findClass (String name, byte [] Classbytes) throws classnotfoundexception {if (ClassBytes == null) {THR ow new ClassNotFoundException ( "(classBytes == null)");} else {return defineClass (name, classBytes, 0, classBytes.length);}} public void execute (String codeName, byte [] code) {Class klass = null Try {klass = Findclass (CODENAME, CODE); Taskintf Task = (Taskintf) Klass.newInstance (); task.execute ();} catch (exception exception) {exception.printStackTrace ();}}

This class FileSystemClassLoader is used by the client to define the Class and converts the client.taskimpl (v1) to Byte [], and then byte [] is then sent to the RMI Server execution. (Tell the defineClass () to execute any bytecode), in the Server side, but also define the client.taskimpl by FileSystemClassLoader as Byte []. CLIENT code:

public class Client {public static void main (String [] args) {try {byte [] code = getClassDefinition ( "client.TaskImpl"); serverIntf.execute ( "client.TaskImpl", code);} catch (RemoteException remoteException) {remoteException.printStackTrace ();}} private static byte [] getClassDefinition (String codeName) {String userDir = System.getProperties () getProperty ( "BytePath");. FileSystemClassLoader fscl1 = null; try {fscl1 = new FileSystemClassLoader (userDir) } Catch (filenotfoundexception) {filenotfoundexception.printStackTrace ();} returnifl1.findclassbytes (codename);}}

In the RMI server server serverImpl program, bytecode (byte []) is accepted (byte []), and FileSystemClassLoader will construct a Class, instantiate, and execute from byte []. One thing to pay attention to: Every time a client is received, FileSystemClassLoad is re-instantified (you can see in the execution result), which means that Client.Impl is not found in the classpath, but through FileSystemClassLoader. FindClass () to perform defineClass (), so each FileSystemClassLoader is created a new instance, natural define Class is also different. In this way, we can distinguish these two classes in the execution of RMI. (Client.taskimpl! = Client.taskimp has been concluded.)

Take a look at the execution code of the server:

public void execute (String codeName, byte [] code) throws RemoteException {FileSystemClassLoader fileSystemClassLoader = null; try {fileSystemClassLoader = new FileSystemClassLoader (); fileSystemClassLoader.execute (codeName, code);} catch (Exception exception) {throw new RemoteException (exception .getMessage ());}} The execution result of the server side:

Figure 10, server side display

The following two figures are displayed by the client.

Figure 11. Execution display of Client1

Figure 12. CLIENT2 execution result

In the same VM virtual machine, execute the code of "different versions" (these code has the same class name and package name), which can be solved.

Class Loaders is applied in J2EE.

Here you are not enough to have something you are now. . .

My A_WAR.WAR's Web Project is com.mycom.test and I am in another B_war.war's wenb project is also com.mycom.test and they still work well.

When a large EJB project, a server deploying multiple EJBs, WAR project, they will not affect each other. AppServer will have its own loading strategy, such as the JAR package in your web, which will take precedence over the Appserver itself.

In addition, J2EE's ClassLoader mechanism can be able to refer to this article on TSS.

Understanding J2ee Application Server Class Loading Architectures

resource:

Original code Sample code article JDK 1.5 API Docs The Java language specification "Understanding Extension Class Loading" in the Java tutorial "Inside Class Loaders" from ONJava "Inside Class Loaders: Debugging" from ONJava "What version is your Java code?" From JavaWorld "Understanding J2ee Application Server Class Loading Architectures" from Theserverside Byte Code Engineering Library Server-Based Java Programming By Ted Neward

Original: http://www.onjava.com/pub/a/onjava/2005/01/26/ClassLoading.htm

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

New Post(0)