Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇

原创 2005年05月29日 01:05:00
 

如何构造使用自定义的ClassLoader

既然自定义的ClassLoader,能解决上述问题,那接下去看看,我们如何来使用自定义的ClassLoader。

结合本文种的原码---(在differentversionspush的目录里),有个FileSystemClassLoader,类图描述如下:


图9.

 

看看他的方法 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){
            throw 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();
        }
    }

这个类FileSystemClassLoader 被client使用了,用来定义class, 并且把它把client.TaskImpl(v1)转化为 byte[], 然后 byte[]发送到RMI Server执行。(上面讲了defineClass()能够执行任何字节码,来自编译后的文件,网络甚至是BCEL 字节码引擎库),   在Server端 ,又可以通过FileSystemClassLoader 以为byte[]的形式定义出 client.TaskImpl。

 

请看Client端的代码:

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){
            fileNotFoundException.printStackTrace();
        }
        return fscl1.findClassBytes(codeName);
    }
}

在RMI服务器端ServerImpl 程序里, 接受到来自client的字节码(byte[]),于是FileSystemClassLoader 会从byte[]构造出一个class, 实例话,并且执行。

有一点要注意:每次接收到一个client的请求,FileSystemClassLoader都会重新实例化(执行结果中可以看出来),这就意味着,client.Impl不在是在classpath中被找到的,而是通过FileSystemClassLoader 的findClass() 来执行deFineClass(),这样每次 FileSystemClassLoader 都是创建新的实例,,自然 deFine出来的class也是不同的。 这样,我们就能在RMI的执行中区分出 这两个class来。(client.TaskImpl != client.TaskImp  在上篇就已经得出结论了。 )

看看服务器端的执行代码:

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());
        }
    }

 

服务器端的执行结果:


图10,服务器端显示

下面两图分别是客户端显示的。


图11. client1的执行显示



图12. client2执行结果

 

哈,上面洋洋洒洒那么多,总算是一步一步的教会了大家 如何在同一个VM虚拟机中,执行“不同版本”的代码 。(这些代码有同样的类名和包名)。

 

Class Loaders 在 J2EE 中应用。

到这里你其实已经不足为奇下面一些东西了。。。
      我的一个A_war.war的web项目中 代码是 com.mycom.Test 而我在另外一个B_war.war的wenb项目中的 代码也是com.mycom.Test 而他们照样工作的好好的。
      当一个大型的 EJB项目,一台服务器上部署了多个 EJB,War工程时候,他们也不会互相影响。AppServer还会有自己的装载策略,比如你web中用的jar包,会优先于AppServer本身所带有的。

原文:
http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.htm

Class Loading ---(类装载机制,开发者不得不知道的故事)

也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然而将诉的内容却包含了最基本的原理,希望你能更加深入了解自己所使用得语言。     理解CL...
  • vvggsky
  • vvggsky
  • 2006年12月14日 17:52
  • 655

Class Loading ---(类装载机制,开发者不得不知道的故事)

也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然而将诉的内容却包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLass...
  • totodo
  • totodo
  • 2005年01月28日 13:15
  • 5690

Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇

如何构造使用自定义的ClassLoader既然自定义的ClassLoader,能解决上述问题,那接下去看看,我们如何来使用自定义的ClassLoader。结合本文种的原码---(在differentv...
  • start_java
  • start_java
  • 2005年06月27日 01:18
  • 1054

Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇

如何构造使用自定义的ClassLoader既然自定义的ClassLoader,能解决上述问题,那接下去看看,我们如何来使用自定义的ClassLoader。结合本文种的原码---(在differentv...
  • totodo
  • totodo
  • 2005年01月28日 21:48
  • 2013

Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇

 也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然后将将诉的内容都包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLa...
  • JEGarden
  • JEGarden
  • 2005年02月04日 16:56
  • 1376

Class Loading ---(类装载机制,开发者不得不知道的故事) --中篇

  我们是否需要自定义的ClassLoader?     理由之一: 如果我们自定义了ClassLoader,那我们便可以控制JVM的加载动作了。      上面说一个class标识是由于packag...
  • totodo
  • totodo
  • 2005年01月28日 21:37
  • 1873

Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇

 也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然后将将诉的内容都包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLa...
  • dazern
  • dazern
  • 2005年05月29日 01:07
  • 1150

Class Loading ---(类装载机制,开发者不得不知道的故事) --中篇

我们是否需要自定义的ClassLoader?     理由之一: 如果我们自定义了ClassLoader,那我们便可以控制JVM的加载动作了。      上面说一个class标识是由于package+...
  • dazern
  • dazern
  • 2005年05月29日 01:07
  • 869

JVM 之 类的装载机制

看到网上有一道面试题:能不能装载自定义的 java.lang.String? 答案是否定的,我们能自定义一个java.lang.String,但是加载不进来。 我相信很多人在网上看到这样的答案“可以...
  • MakeContral
  • MakeContral
  • 2017年10月28日 12:28
  • 210

Java你可能不知道的事系列1

概述本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解。如果有不对的地方还请各位观众拍砖。 今天主要分享一下常用的字符串的几个题目,相信学习java的小伙伴们对String类是再熟...
  • yissan
  • yissan
  • 2016年03月06日 00:39
  • 2112
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇
举报原因:
原因补充:

(最多只允许输入30个字)