由于当于开发需要,需要利用JAVA的ClassLoader进行动态类的加载,结构可能如下:
1、AppMain.jar   //系统主程序,Main函数在其中。
   在这个包中存在一个接口类:BaseBusinessLogic的interface,
   有一方法 public void parse(Strig strMsg);也就是我的业逻辑必需从此类进行继承了,比如说 我有一个新类:OneBL;
  public class OneBL implements {
    public void parse(String strMsg) {
      /*在此写入相关业务逻辑*/
      ...
      ...
      return ;
    }
  }现在是系统AppMain.jar文件只有在需要的时候才调用此方法,有可能需要其它的方法,同样其它的方法也需从BaseBusinessLogic接口继承,此时,主程序已经运行了,将新写的继承类编译打包后,放到主程序能够访问的目录中,通过配置文件的方式,在主程序需要调用继承类时加载此方法,也就是问题的主题:ClassLoader的应用了。
如果编译后的文件不进行打包(打成JAR包),是可以利用ClassLoader进行读取并执行其它的方法,现想把编译后的文件打成JAR包,不知道如何实现呀!

解决方案 »

  1.   

    动态加载类:
    package com.xwn.tool;import java.lang.ClassLoader;
    import java.io.File;
    import java.io.IOException;
    import java.io.FileInputStream;
    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileNotFoundException;
    /**
     *
     * @author xwn
     */
    public class ClassLoaderAdaper extends ClassLoader {
        
        /** Creates a new instance of ClassLoaderAdaper */
        public ClassLoaderAdaper(String strBasePath) {
            //super();
            this.m_strBasePath = strBasePath;
        }
        
        
        public synchronized Class loadClass(String className,
            boolean resolveIt) throws ClassNotFoundException {
            Class pclass        = null;
            byte byteclass[]    = null;
            
            pclass = findLoadedClass(className);
            
            if (null != pclass) {
                return pclass;
            }
            
            if (className.compareTo("Spoofed") != 0) {
                try {
                    pclass = super.findSystemClass(className);
                    // Return a system class
                    return pclass;
                }
                catch (ClassNotFoundException e) {
                }
            }
            
            if (className.startsWith("java.")) {
                throw new ClassNotFoundException();
            }
            
            byteclass = getTypeFromBasePath(className);
            if (byteclass == null) {
                System.out.println("无法正确构造类型,类加载器执行失败,加载类: "
                    + className);
                throw new ClassNotFoundException();
            }
            
            pclass = defineClass(className, byteclass, 0,
                byteclass.length);
            
            if (pclass == null) {
                System.out.println("无法正确构造类型,类加载格式错误,加载类: "
                    + pclass);
                throw new ClassFormatError();
            }        if (resolveIt) {
                resolveClass(pclass);
            }        // Return class from basePath directory
            System.out.println("类加载器返回,pclass.toString() = " + pclass.toString());
            return pclass;
        }
        
        private byte[] getTypeFromBasePath(String typeName) {        FileInputStream fis;
            String fileName = m_strBasePath + File.separatorChar
                + typeName.replace('.', File.separatorChar)
                + ".class";
            System.out.println("fileName: " + fileName);
            try {
                fis = new FileInputStream(fileName);
            }
            catch (FileNotFoundException e) {
                return null;
            }        BufferedInputStream bis = new BufferedInputStream(fis);        ByteArrayOutputStream out = new ByteArrayOutputStream();        try {
                int c = bis.read();
                while (c != -1) {
                    out.write(c);
                    c = bis.read();
                }
            }
            catch (IOException e) {
                return null;
            }        return out.toByteArray();
        }
        
        private String m_strBasePath = null; // 加载类路径
    }
      

  2.   

    接口类:
    package com.xwn.businesslogic;/**
     *
     * @author xwn
     */
    public interface HelloInterface {
        public void run();
    }
      

  3.   

    现在可能需要经常从public interface HelloInterface 继承新的类进行扩展程序,而主程序是不需停止即可添加新的业务模块,新写的业务逻辑可能需要打成相应的JAR文件包,主程序动态进行调用此文件JAR包中的业,唉,不会啊,谁能帮我呀!
      

  4.   

    jar路径搜索的顺序或优先级别的问题.
    1.缺省值:调用Java或javawa的当前路径(.),是开发的class所存在的当前目录
    2. CLASSPATH环境变量设置的路径.如果设置了CLASSPATH,则CLASSPATH的值会覆盖缺省值
    3. 执行Java的命令行-classpath或-cp的值,如果制定了这两个命令行参数之一,它的值会覆盖环境变量CLASSPATH的值
    4. -jar 选项:如果通过java -jar 来运行一个可执行的jar包,这当前jar包会覆盖上面所有的值.换句话说,-jar 后面所跟的jar包的优先级别最高,如果指定了-jar选项,所有环境变量和命令行制定的搜索路径都将被忽略.JVM APPClassloader将只会以jar包为搜索范围.这也是为什么应用程序打包成可执行的jar包后,不能引用第三方jar包的原因.
    解决方案:
    1.将需要的第三方的jar包,复制在同可执行jar所在的目录或某个子目录下.
    比如:jar 包在 d:\crm\luncher.jar 那么你可以把所有jar包复制到d:\crm目录下或d:\crm\lib 子目录下.
    2.修改Manifest 文件
    在Manifest.mf文件里加入如下行
    Class-Path:classes12.jar lib/class12.jar