一个外部jar文件,有两个类:
/**
*
*/
package dynamic.test2;public class Personal extends Object{ private String name="";
private int age = 0;
private boolean isMale = true;
/**
*
*/
public String toString(){
return this.getClass().getName()+": "+name+"@"+age+"@"+isMale;
}
public Personal() {
// TODO Auto-generated constructor stub
}
public Personal(String _name,int _age,boolean _ismale){
this.name = _name;
this.age = _age;
this.isMale = _ismale;
}
public void setName(String value){
this.name = value;
}
public String getName(){
return this.name;
}
public void setAge(int value){
this.age = value;
}
public int getAge(){
return this.age;
}
public void setMale(boolean value){
this.isMale = value;
}
public boolean isMale(){
return this.isMale==true;
}}=====
/**
*
*/
package dynamic.test2;import java.util.ArrayList;
import java.util.List;public class Group { private List<Personal> peoples = new ArrayList<Personal>();
/**
*
*/
public Group() {
// TODO Auto-generated constructor stub
} public void add(){
Personal item = new Personal("auto",0,true);
peoples.add(item);
}
public void add(String name,int age,boolean ismale){
Personal item = new Personal(name,age,ismale);
peoples.add(item);
}
public void add(Personal item){
peoples.add(item);
}
public List getPersonals(){
return this.peoples;
}
}生成外部的test2.jar
写一个测试程序,采用反射原理,动态的加载了test2.jar文件 ,调用dynamic.test2.Group.add()后,再调用dynamic.test2.Group.getPersonals()来得到list. 出错代码如下:
...
fm.executeFunction("add", new Object[0],cinst);
List list = (List)fm.executeFunction("getPersonals", new Object[0],cinst);//正常
if(list==null){
System.out.println("result is null");
}
else{
System.out.println(list.size()); //正常,得到大小 =1
Iterator it = list.iterator(); //正常
while(it.hasNext()){
Object o = it.next();
System.out.println(o.getClass().getName()); //正常,输出就是 dynamic.test2.Personal
Personal item = (Personal)o; //这句就出错了:java.lang.ClassCastException: dynamic.test2.Personal cannot be cast to dynamic.test2.Personal
System.out.println(item.getName()+" "+ item.getAge()+" "+item.isMale());
}
}
...这个问题不知怎样解决?
/**
*
*/
package dynamic.test2;public class Personal extends Object{ private String name="";
private int age = 0;
private boolean isMale = true;
/**
*
*/
public String toString(){
return this.getClass().getName()+": "+name+"@"+age+"@"+isMale;
}
public Personal() {
// TODO Auto-generated constructor stub
}
public Personal(String _name,int _age,boolean _ismale){
this.name = _name;
this.age = _age;
this.isMale = _ismale;
}
public void setName(String value){
this.name = value;
}
public String getName(){
return this.name;
}
public void setAge(int value){
this.age = value;
}
public int getAge(){
return this.age;
}
public void setMale(boolean value){
this.isMale = value;
}
public boolean isMale(){
return this.isMale==true;
}}=====
/**
*
*/
package dynamic.test2;import java.util.ArrayList;
import java.util.List;public class Group { private List<Personal> peoples = new ArrayList<Personal>();
/**
*
*/
public Group() {
// TODO Auto-generated constructor stub
} public void add(){
Personal item = new Personal("auto",0,true);
peoples.add(item);
}
public void add(String name,int age,boolean ismale){
Personal item = new Personal(name,age,ismale);
peoples.add(item);
}
public void add(Personal item){
peoples.add(item);
}
public List getPersonals(){
return this.peoples;
}
}生成外部的test2.jar
写一个测试程序,采用反射原理,动态的加载了test2.jar文件 ,调用dynamic.test2.Group.add()后,再调用dynamic.test2.Group.getPersonals()来得到list. 出错代码如下:
...
fm.executeFunction("add", new Object[0],cinst);
List list = (List)fm.executeFunction("getPersonals", new Object[0],cinst);//正常
if(list==null){
System.out.println("result is null");
}
else{
System.out.println(list.size()); //正常,得到大小 =1
Iterator it = list.iterator(); //正常
while(it.hasNext()){
Object o = it.next();
System.out.println(o.getClass().getName()); //正常,输出就是 dynamic.test2.Personal
Personal item = (Personal)o; //这句就出错了:java.lang.ClassCastException: dynamic.test2.Personal cannot be cast to dynamic.test2.Personal
System.out.println(item.getName()+" "+ item.getAge()+" "+item.isMale());
}
}
...这个问题不知怎样解决?
classloader是这样的:
URLClassLoader loader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class cls = loader.loadClass("test2.jar");
...
*
*/
package dynamic.functions;import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;public class FunctionItem implements Comparable{ private String name="";
private String excutePoint="";
private boolean isAllow=true;
private int priority=0;
private String className="";
private String url="";
private String description="";
private List paramsType = new ArrayList();
private String resultType=null;
private Class instance=null;
private ClassLoader loader = null; private Map<String,Object> attributes = new HashMap<String,Object>();
/**
*
*/
public FunctionItem() {
// TODO Auto-generated constructor stub
}
public void attributeValue(String key,Object value){
this.attributes.put(key, value);
}
public Object attribute(String key){
return this.attributes.get(key);
}
public void setClass1(Class object){
this.instance = object;
}
public Class getClass1(){
return this.instance;
}
@SuppressWarnings("finally")
public Object newInstance(){
Object rlt = null;
try {
rlt=this.loader.loadClass(this.className).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
return rlt;
}
}
public void setClassLoader(ClassLoader object){
this.loader = object;
}
public ClassLoader getClassLoader(){
return this.loader;
}
public void setResultType(String value){
this.resultType = value;
}
public String getResultType(){
return this.resultType;
}
public void addParamType(String type){
this.paramsType.add(type);
}
public List getParamType(){
return this.paramsType;
}
public Iterator iteratorParams(){
return this.paramsType.iterator();
}
public int sizeParams(){
return this.paramsType.size();
}
public void clearParamsType(){
this.paramsType.clear();
}
public void setClassName(String value){
this.className = value;
}
public String getClassName(){
return this.className;
}
public void allow(boolean value){
this.isAllow = value;
}
public boolean isAllow(){
return this.isAllow==true;
}
public void setName(String value){
this.name = value;
}
public String getName(){
return this.name;
}
public void setExcutePoint(String value){
this.excutePoint = value;
}
public String getExcutePoint(){
return this.excutePoint;
}
public String getURL(){
return this.url;
}
public void setURL(String value){
this.url = value;
}
public void setDescription(String value){
this.description = value;
}
public String getDescription(){
return this.description;
}
public int getPriority(){
return this.priority;
}
public void setPriority(int value){
this.priority = value;
} public String toString(){
return this.getClass().getName()+":name="+this.getName()+"@"
+"url="+this.getURL()+"@"
+"priority="+this.getPriority()+"@"
+"allow="+this.isAllow+"@"
+"classname="+this.getClassName()+"@"
+"description="+this.getDescription();
}
@Override
public int compareTo(Object obj) {
// TODO Auto-generated method stub
if(obj instanceof FunctionItem){
FunctionItem other = (FunctionItem)obj;
if(getPriority()>other.getPriority()){
return 1;
}
else if(getPriority()<other.getPriority()){
return -1;
}
return 0;
}
else if(obj instanceof Comparable){
return -((Comparable)obj).compareTo(this);
}
else{
throw new java.lang.IllegalArgumentException();
} }}
import dynamic.DynamicClassLoadEventListener;
import dynamic.DynamicClassLoadHandler;
import dynamic.MethodUtil;
/**
*
* 1. set configFile;
* 2. run;
*/
public class FunctionManager { private String configFile = "file://"+System.getProperty("user.dir")+"/dynamic/dynamic.config";
private java.util.Timer timer=null;
private int checkPeriod = 6000;
private List<FunctionItem> functions = new LinkedList<FunctionItem>();
private DynamicClassLoadHandler dynamicHandler ;
private DynamicClassLoad dynamicLoad ;
private DynamicClassLoadEventListener dynamicListener ;
private long flength=0;
private long fmodified = 0;
/**
*
*/
public FunctionManager() {
// TODO Auto-generated constructor stub
dynamicHandler = new LoadHandler();
dynamicLoad = new DynamicClassLoad(dynamicHandler);
dynamicLoad.setRelationParentLoader(true);
dynamicLoad.setLoader(this.getClass().getClassLoader());
dynamicListener = new LoadEventListener(dynamicLoad,this);
dynamicLoad.addListener(dynamicListener);
}
public void setConfigURL(String url){
this.configFile = url;
}
public String getConfigFile(){
return this.configFile;
}
public void setCheckPeriod(int msecond){
this.checkPeriod = msecond;
}
public int getCheckPeriod(){
return this.checkPeriod;
}
private void addFunctionItem(FunctionItem item){
this.functions.add(item);
}
public int size(){
return this.functions.size();
}
public Iterator iteratorFunctions(){
return this.functions.iterator();
}
private void clearFunctions(){
this.functions.clear();
} public void checkAll() {
// TODO Auto-generated method stub
URL url;
InputStream in;
URLConnection uc;
try {
url = new URL(this.configFile);
in = url.openStream();
uc = url.openConnection();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return ;
} catch(IOException e){
e.printStackTrace();
return;
}
long size = uc.getContentLength();
long lastmodify = uc.getLastModified();
if(flength==size && fmodified == lastmodify) return;
flength=size;
fmodified = lastmodify;
SAXReader rdr = new SAXReader();
Document document=null;
try {
document = rdr.read(in);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
clearFunctions();
Node node = document.selectSingleNode("/functions");
if(node==null){
return;
}
List list = node.selectNodes("functionItem");
for(Object o : list){
Element e = (Element)o;
FunctionItem fitem = new FunctionItem();
fitem.setName(e.attributeValue("name") );
fitem.setExcutePoint(e.attributeValue("excutepoint"));
fitem.setClassName(e.attributeValue("classname"));
fitem.setDescription(e.attributeValue("description"));
fitem.setURL(e.attributeValue("url"));
String v = e.attributeValue("allow");
boolean bv = false;
if(v==null){
bv=false;
}
else{
if(v.toLowerCase().equals("true") || Integer.valueOf(v).intValue()==1){
bv=true;
}
}
fitem.allow(bv);
v=e.attributeValue("priority");
int iv = 0;
if(v==null){
iv=0;
}
else{
iv = Integer.valueOf(v).intValue();
}
fitem.setPriority(iv);
List plist= e.selectNodes("paramsType/param");
for(Object op:plist){
Element ep =(Element)op;
fitem.addParamType(ep.attributeValue("type"));
} Element eer = (Element) e.selectSingleNode("resultType");
fitem.setResultType(eer.attributeValue("type"));
addFunctionItem(fitem);
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(this.functions);
Iterator it = this.iteratorFunctions();
while(it.hasNext()){
FunctionItem item = (FunctionItem)it.next();
dynamicLoad.addURL(item.getURL());
dynamicLoad.addClass(item.getURL(), item.getClassName());
}
dynamicLoad.reload();
}
this.timer = new Timer(true);
this.timer.schedule(new CheckDynamic(this), 0,this.checkPeriod);
} public FunctionItem getFunctionItem(String name){
if(name==null || name.trim().length()<=0) return null;
Iterator it = this.iteratorFunctions();
while(it.hasNext()){
FunctionItem item = (FunctionItem)it.next();
if(item.getName().toLowerCase().equals(name.toLowerCase())){
return item;
}
}
return null;
} public FunctionItem getFunctionItem(String name,Object[] params){
if(name==null || name.trim().length()<=0) return null;
if(params.length<=0) return getFunctionItem(name);
Iterator it = this.iteratorFunctions();
while(it.hasNext()){
FunctionItem item = (FunctionItem)it.next();
if(item.getName().toLowerCase().equals(name.toLowerCase())){
List lstParam = item.getParamType();
boolean bMatched = true;
//System.out.println(item.getName()+":"+params.length+" : "+lstParam.size());
if(params.length== lstParam.size()){
for(int i = 0 ; i < params.length; i++){
Class c = params[i].getClass();
boolean bM = false;
if(!lstParam.contains(c.getName())){
Class nc = c.getSuperclass();
while(nc!=Object.class){
if(lstParam.contains(nc.getName())){
bM=true;
break;
}
nc=nc.getSuperclass();
}
if(bM){
bMatched=true;
break;
}
}
else{
bMatched = true;
break;
}
}
//System.out.println("name isMatched:"+bMatched);
if (bMatched){
return item;
}
}
}
}
return null;
}
public FunctionItem getFunctionItem(String name,String[] paramTypes){
if(name==null || name.trim().length()<=0) return null;
if(paramTypes.length<=0) return getFunctionItem(name);
Iterator it = this.iteratorFunctions();
while(it.hasNext()){
FunctionItem item = (FunctionItem)it.next();
if(item.getName().toLowerCase().equals(name.toLowerCase())){
List lstParam = item.getParamType();
boolean bMatched = true;
if(paramTypes.length== lstParam.size()){
for(int i = 0 ; i < paramTypes.length; i++){
String clsn = paramTypes[i];
if(!lstParam.contains(clsn)){
bMatched = false;
break;
}
}
if (bMatched){
return item;
}
}
}
}
return null;
}
@SuppressWarnings("finally")
public Object executeFunction(String name,Object[] params,Object classInstance){
FunctionItem function = this.getFunctionItem(name, params);
if(function==null) return null;
MethodUtil mu = new MethodUtil();
Iterator it = function.iteratorParams();
Class[] ppp =new Class[function.sizeParams()];
try {
int index=0;
while(it.hasNext()){
String clsname = (String)it.next();
ppp[index++] = function.getClassLoader().loadClass(clsname); }
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
Method method = mu.getMethod(function.getClass1(), function.getExcutePoint(), ppp );
if (method==null) return null;
Object result=null;
try {
method.setAccessible(true);
Object instance = classInstance;
if(instance==null){
instance = function.getClassLoader().loadClass(function.getClassName()).newInstance();
}
result = method.invoke(instance, params);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
return result;
} }
}
另外,你的FunctionManager代码里也没有fm.executeFunction()方法啊。
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;import sun.misc.Launcher;/**
* @author wq7x
* Title: 使用事件的类
* Description: 该类实现了监听器的添加和监听器方法的执行,并且实现了由于属性的改变而执行事件
* Description: 在添加、删除、执行监听器的时候都要注意同步问题
*/
public class DynamicClassLoad {
private static List<String> paths;
private static Map<String,Set> classes;
private static Field packages;
private static URLClassLoader loader ;
private DynamicClassLoadHandler reloadHandler ;
private ClassLoader parentLoader;
private boolean relationParentLoader=true;
private Map attributes = new HashMap();
private Vector repository = new Vector(); private DynamicClassLoadEventListener listener;
/**
*
*/
public DynamicClassLoad() {
// TODO Auto-generated constructor stub
paths = new ArrayList<String>();
classes = new HashMap<String,Set>();
loader = (URLClassLoader) ClassLoader.getSystemClassLoader();
parentLoader = this.getLoader().getParent();
}
public DynamicClassLoad(DynamicClassLoadHandler handler){
paths = new ArrayList<String>();
classes = new HashMap<String,Set>();
loader = (URLClassLoader) ClassLoader.getSystemClassLoader();
parentLoader = this.getLoader().getParent();
reloadHandler = handler;
} public void setLoader(ClassLoader clsl){
this.loader = (URLClassLoader)clsl;
if(parentLoader==null) parentLoader = this.getLoader().getParent();
}
public void setParentLoader(ClassLoader parent){
parentLoader = parent;
}
public void setRelationParentLoader(boolean value){
this.relationParentLoader = value;
}
/**
* 注册监听器,如果这里没有使用Vector而是使用ArrayList那么要注意同步问题
* @param dl
*/
public void addListener(DynamicClassLoadEventListener listener) {
repository.addElement(listener);//这步要注意同步问题
}
/**
* 如果这里没有使用Vector而是使用ArrayList那么要注意同步问题
* @param event
*/
public void notifyEvent(DynamicClassLoadEvent event) {
Enumeration enu = repository.elements();//这步要注意同步问题
while (enu.hasMoreElements()) {
listener = (DynamicClassLoadEventListener) enu.nextElement();
listener.doEvent(event);
}
}
/**
* 删除监听器,如果这里没有使用Vector而是使用ArrayList那么要注意同步问题
* @param listener
*/
public void removeDemoListener(DynamicClassLoadEventListener listener) {
repository.remove(listener);//这步要注意同步问题
}
public static ClassLoader getLoader(){
return loader;
}
public static List<String> getPaths(){
return paths;
}
/**
* Map<文件,类名集合Set>
* @return
*/
public static Map<String,Set> getClasses(){
return classes;
}
public Set classesByKey(String key){
if(classes.containsKey(key)){
return (Set)classes.get(key);
}
return null;
}
public DynamicClassLoadHandler getReloadHandler(){
return reloadHandler;
}
public void setPaths(List<String> list){
paths = list;
}
public void setDynamicClassLoadHandler(DynamicClassLoadHandler handler){
this.reloadHandler = handler;
}
public void addURL(String value){
if(!paths.contains(value)){
paths.add(value);
}
}
public void setClasses(Map<String,Set> map){
classes = map;
}
public void addClass(String keyPathFile,String valueClass){
Set set;
if(classes.containsKey(keyPathFile)){
set = (Set)classes.get(keyPathFile);
}
else{
set = new HashSet();
}
if(!set.contains(valueClass)){
set.add(valueClass);
}
classes.put(keyPathFile, set);
}
public void attributeValue(String key,Object value){
this.attributes.put(key,value);
}
public Object attribute(String key){
return this.attribute(key);
}
public URL[] getBootstrapURLs() {
return Launcher.getBootstrapClassPath().getURLs();
} public URL[] getSystemURLs() {
return ((URLClassLoader)ClassLoader.getSystemClassLoader()).getURLs();
} public URL[] getExtURLs() {
return ((URLClassLoader)ClassLoader.getSystemClassLoader().getParent()).getURLs();
}
private void list(PrintStream ps, URL[] classPath) {
for (int i = 0; i < classPath.length; i++) {
ps.println(classPath[i]);
}
}
public void listBootstrapClassPath() {
listBootstrapClassPath(System.out);
} public void listBootstrapClassPath(PrintStream ps) {
ps.println("BootstrapClassPath:");
list(ps, getBootstrapClassPath());
} public void listSystemClassPath() {
listSystemClassPath(System.out);
} public void listSystemClassPath(PrintStream ps) {
ps.println("SystemClassPath:");
list(ps, getSystemClassPath());
} public void listExtClassPath() {
listExtClassPath(System.out);
} public void listExtClassPath(PrintStream ps) {
ps.println("ExtClassPath:");
list(ps, getExtClassPath());
}
public URL[] getBootstrapClassPath() {
return getBootstrapURLs();
} public URL[] getSystemClassPath() {
return getSystemURLs();
} public URL[] getExtClassPath() {
return getExtURLs();
} public void reload(){
Iterator it = paths.iterator();
URL url;
File file ;
List<String> filenames= new ArrayList<String>();
while(it.hasNext()){
String path = (String)it.next();
InputStream in;
boolean bfile=true;
try {
System.out.println(path);
url = new URL(path);
in = url.openStream();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
bfile=false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
bfile=false;
}
if(bfile)
filenames.add(path);
}
it = filenames.iterator();
String pathfile;
Set clss;
while(it.hasNext()){
pathfile = (String)it.next();
if(reloadHandler.beforeReload(pathfile)){
try {
url = new URL(pathfile);
if(relationParentLoader)
loader = new URLClassLoader(new URL[]{url},parentLoader);
else
loader = new URLClassLoader(new URL[]{url});
clss=classesByKey(pathfile);
if(clss!=null){
for(Iterator iii = clss.iterator(); iii.hasNext();){
String clsname = (String)iii.next();
Class nCls = loader.loadClass(clsname);
DynamicClassLoadEvent event = new DynamicClassLoadEvent(loader,pathfile,nCls);
event.attributeValue("className", clsname);
notifyEvent(event);
}
}
reloadHandler.afterReload(pathfile);
//激活重新装入后的事件
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}}
----
7楼已经说了要点了。我也是怀疑你的fm代码里有这个问题。