一个思路:我把业务代码封装到jar包里,然后在程序中动态加载jar包,把方法反射出来然后执行业务逻辑。
核心业务是这么写的
String decodeClass = "";
String decodeJarPath = "";
decodeClass = profile.getDecodeClass();
decodeJarPath = profile.getDecodeJar();
if(Strings.isBlank(decodeClass)||Strings.isBlank(decodeJarPath)){
log.error("JAR或CLASS名称为空");
return null;
}
try {
Class decodeclass = null;
log.error("当前运行路径为"+System.getProperty("user.dir"));
try {
decodeclass = urlClassLoader.loadClass(decodeClass);
} catch (ClassNotFoundException e) {
log.error("加载失败,去"+System.getProperty("user.dir")+"/"+decodeJarPath+"加载jar包");
URL url = new File(System.getProperty("user.dir")+"/"+decodeJarPath).toURI().toURL();
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
add.setAccessible(true);
add.invoke(urlClassLoader, new Object[] {url});
}
try{
decodeclass = urlClassLoader.loadClass(decodeClass);
}catch (ClassNotFoundException e) {
log.error("第二次依然加载失败!退出");
return null;
}
if(decodeclass==null){
log.error("加载失败!");
return null;
}
log.error("加载"+System.getProperty("user.dir")+"/"+decodeJarPath+"包成功");
Method method = null;
Object object = null;
try {
object = decodeclass.getDeclaredConstructor().newInstance();
method = decodeclass.getDeclaredMethod(Common.MqttTran.METHOD,byte[].class);
} catch (MethodNotFoundException e){
log.error(Common.MqttTran.METHOD+"方法无法找到");
return null;
} catch (NoSuchMethodException e) {
log.error("对象中没有此方法");
return null;
} catch (Exception e) {
log.error("异常错误");
return null;
}
log.error(Common.MqttTran.METHOD+"方法已找到"+method.toString());
if(method==null){
log.error("找不到"+Common.MqttTran.METHOD+"方法");
return null;
}
Map ret = (Map)method.invoke(object,message.getPayload());
核心逻辑在这里
加载的时候用的是classloader的addURL方法,它会把jar包放到classpath里去,这样的话会导致jar包里的所有的类都被加载
但是我的jar包里有很多不必要的测试类,引用了org/eclipse/paho/client/mqttv3/MqttException类
所以就报了上面的错误。
解决办法:应用此方案,jar包需要是个FatJar,必须包含所有引用的类
在此案例里,我把测试代码都清理掉就好了,但是也有个问题,以后每次测试都需要重新写这些代码。
先这样吧,后面有时间再研究
?
?
|