由于当于开发需要,需要利用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、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包,不知道如何实现呀!
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; // 加载类路径
}
package com.xwn.businesslogic;/**
*
* @author xwn
*/
public interface HelloInterface {
public void run();
}
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