今天突然想到可不可以动态的去加载添加的类,这样可以省去以后添加类时候修改的麻烦。借鉴前人的
部分经验得到如下代码:
package cn.yyzx.util;
import Java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class FindPackageClass {
public static void main(String []args){
// String ss="cn.yyzx.test.TestC";
// try {
// Thread a=(Thread) Class.forName(ss).newInstance();
// a.start();
// } catch (Exception e) {
// e.printStackTrace();
// }
List cls = getClassInPackage("cn.yyzx.msgsend");
for(String s:cls){
System.out.println(s);
}
}
public static List getClassInPackage(String pkgName) {
List ret = new ArrayList();
String rPath = pkgName.replace('.', '/') + "/";
try {
for (File classPath : CLASS_PATH_ARRAY) {
if (!classPath.exists())
continue;
if (classPath.isDirectory()) {
File dir = new File(classPath, rPath);
if (!dir.exists())
continue;
for (File file : dir.listFiles()) {
if (file.isFile()) {
String clsName = file.getName();
clsName = pkgName
+ "."
+ clsName
.substring(0, clsName.length() - 6);
ret.add(clsName);
}
}
} else {
FileInputStream fis = new FileInputStream(classPath);
JarInputStream jis = new JarInputStream(fis, false);
JarEntry e = null;
while ((e = jis.getNextJarEntry()) != null) {
String eName = e.getName();
if (eName.startsWith(rPath) && !eName.endsWith("/")) {
ret.add(eName.replace('/', '.').substring(0,
eName.length() - 6));
}
jis.closeEntry();
}
jis.close();
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return ret;
}
private static String[] CLASS_PATH_PROP = { "java.class.path",
"java.ext.dirs", "sun.boot.class.path" };
private static List CLASS_PATH_ARRAY = getClassPath();
private static List getClassPath() {
List ret = new ArrayList();
String delim = ":";
if (System.getProperty("os.name").indexOf("Windows") != -1)
delim = ";";
System.out.println(System.getProperty("os.name"));
for (String pro : CLASS_PATH_PROP) {
String[] pathes = System.getProperty(pro).split(delim);
for (String path : pathes){
System.out.println(path);
ret.add(new File(path));}
}
return ret;
}
}
用JDK测试没问题,但到TOMCAT上却无法加载项目的类路径。代码要做修改,先做以上备份。
问题出在 System.getProperty("java.class.path")无法获得项目路径
最后为了简化起见,在web.xml中配置项目路径 然后不搜索系统类
//servlet
public void init(ServletConfig config) throws ServletException {
String path=config.getInitParameter("cpath");
try {
List channel = FindPackageClass.getClassInPackage("cn.yyzx.msgsend",path);
for (String ss : channel) {
Runnable nc = (Runnable) Class.forName(ss).newInstance();
new Thread(nc).start();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
this.init();
}
package cn.yyzx.util;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class FindPackageClass {
public static void main(String[] args) {
List cls = getClassInPackage("cn.yyzx.msgsend", "");
for (String s : cls) {
System.out.println(s);
}
}
public static List getClassInPackage(String pkgName, String path) {
List ret = new ArrayList();
String rPath = pkgName.replace('.', '/') + "/";
try {
File classPath = new File(path);
if (classPath.isDirectory()) {
File dir = new File(classPath, rPath);
for (File file : dir.listFiles()) {
if (file.isFile()) {
String clsName = file.getName();
clsName = pkgName + "."
+ clsName.substring(0, clsName.length() - 6);
ret.add(clsName);
}
}
} else {
FileInputStream fis = new FileInputStream(classPath);
JarInputStream jis = new JarInputStream(fis, false);
JarEntry e = null;
while ((e = jis.getNextJarEntry()) != null) {
String eName = e.getName();
if (eName.startsWith(rPath) && !eName.endsWith("/")) {
ret.add(eName.replace('/', '.').substring(0,
eName.length() - 6));
}
jis.closeEntry();
}
jis.close();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return ret;
}
}
ok = .:. =