此问题与之前通过Unable to invoke method by java reflection: NoSuchMethodException
报告的错误略有不同
重载方法的签名遵循如下目标类,我的目标是动态调用public List run(FileInput,StreamOutput)
。
public List run(String, String);
public List run(FileInput,StreamOutput);
案例1:当CLASS_PATH中存在目标类(jar)时,使用反射api动态加载方法时,方法可以访问。
Class mapClass = loader.loadClass("com.sample.test.TrackingService");
FileInput input = new FileInput(inputFileFullPath);
StreamOutput output = new StreamOutput(new java.io.ByteArrayOutputStream());
Object mapObj = mapClass.newInstance();
Class params[]={ FileInput.class,StreamOutput.class};
Method m = mapClass.getDeclaredMethod("run", params);
outputList = (List) m.invoke(mapObj, input,output);`
案例2:在案例1中的相同代码之上,而不是将jar放在CLASS_PATH中,而是通过URLClassLoader
加载,然后它会抛出NoSuchMethodException
代码块
URL urls[] = {new URL("file:/opt/jars/Tracking.jar")};
URLClassLoader loader = new URLClassLoader(urls);
Class mapClass = loader.loadClass("com.sample.test.TrackingService",true,loader);
FileInput input = new FileInput(inputFileFullPath);
StreamOutput output = new StreamOutput(new java.io.ByteArrayOutputStream());
Object mapObj = mapClass.newInstance();
Class params[]={ FileInput.class,StreamOutput.class};
Method m = mapClass.getDeclaredMethod("run", params);
outputList = (List) m.invoke(mapObj, input,output);
在行Method m = mapClass.getDeclaredMethod("run", params);
问题1:通过URLClassLoader加载课程时是否缺少某些内容?
问题2:有关通过自定义类将类定义加载到JVM的任何建议。我的意思是,达到与CLASS_PATH中存在的jar文件相同的级别?我们的要求和限制的一部分,我们不能将jar放在CLASS_PATH下或将jar路径添加到CLASS_PATH
答案 0 :(得分:0)
两个代码之间应该改变的一切(一个使用ClassLoader,另一个使用URLClassLoader)是实例化,即
此:
ClassLoader loader = getClass().getClassLoader();
Class<?> myLib = loader.loadClass("com.chetan.loader.MyLib");
应替换为:
URL url[] = {new URL("file:C:\\Chetan\\mylib-0.0.1-SNAPSHOT.jar")};
URLClassLoader loader = new URLClassLoader(url);
Class<?> myLib = loader.loadClass("com.chetan.loader.MyLib");
这是我推荐的内容,虽然你可能已经尝试过这些东西,但是如果你没有:
解压缩Jar /opt/jars/Tracking.jar
(您可以通过Winzip或其他类似工具打开它),然后反编译类TrackingService
- 检查它是否包含您尝试调用的方法
为您提供新的代码/模拟 - 我建议使用两种方法变体创建一个小类。把它装在一个罐子里。创建一个测试加载器类并尝试使用URLClassLoader
- 这将使您确信您编写的代码有效。然后,您可以查找问题的其他方面。
无论如何,如果以上建议有效,请告诉我。如果您无法使测试类正常工作,请共享代码,以便此处的成员可以更好地了解您要执行的操作。
答案 1 :(得分:0)
当类加载器改变时,如下所示。
URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/opt/jars/Tracking.jar") }, this.getClass().getClassLoader());
休息一切......就像我说的那样,没有添加当前的类加载器也可以在eclipse中运行时工作。