通过 URLClassLoader 加载 class 时出现 NoSuchMethodException 异常
NoSuchMethodException exception when class is loaded via URLClassLoader
这个问题与之前通过
报告的错误略有不同
重载方法的签名如下在目标 class 中,我的 objective 是动态调用 public List run(FileInput,StreamOutput)
。
public List run(String, String);
public List run(FileInput,StreamOutput);
案例 1:使用反射动态加载方法时 api 当目标 class(jar) 存在于 CLASS_PATH 中时 - 方法可访问.
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 加载 class 时是否缺少某些内容?
问题 2:关于通过自定义 class 将 class 定义加载到 JVM 的任何建议。我的意思是,达到与 CLASS_PATH 中存在的 jar 文件相同的水平?我们的部分要求和限制是我们不能将 jar 放在 CLASS_PATH 下或将 jar 路径添加到 CLASS_PATH
两个代码(一个使用 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 或其他类似的实用程序打开它),然后反编译 class TrackingService
- 检查是否可以包含您要调用的方法?
让您的代码焕然一新/模拟 - 我建议使用两种方法变体创建一个小的 class。把它装在一个罐子里。创建一个测试加载器 class 并尝试使用 URLClassLoader
- 这会让您相信您编写的代码可以正常工作。然后您可以查找问题的其他方面。
无论如何,如果以上建议有效,请告诉我。如果您无法使测试 class 正常工作,请分享代码,以便这里的其他成员可以更好地理解您正在尝试做什么。
它在 class 加载程序更改时起作用,如下所示。
URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/opt/jars/Tracking.jar") }, this.getClass().getClassLoader());
其他一切都一样...正如我所说,不添加当前 class 加载程序在 运行 在 eclipse 中时也能正常工作。
这个问题与之前通过
重载方法的签名如下在目标 class 中,我的 objective 是动态调用 public List run(FileInput,StreamOutput)
。
public List run(String, String);
public List run(FileInput,StreamOutput);
案例 1:使用反射动态加载方法时 api 当目标 class(jar) 存在于 CLASS_PATH 中时 - 方法可访问.
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 加载 class 时是否缺少某些内容?
问题 2:关于通过自定义 class 将 class 定义加载到 JVM 的任何建议。我的意思是,达到与 CLASS_PATH 中存在的 jar 文件相同的水平?我们的部分要求和限制是我们不能将 jar 放在 CLASS_PATH 下或将 jar 路径添加到 CLASS_PATH
两个代码(一个使用 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 或其他类似的实用程序打开它),然后反编译 classTrackingService
- 检查是否可以包含您要调用的方法?让您的代码焕然一新/模拟 - 我建议使用两种方法变体创建一个小的 class。把它装在一个罐子里。创建一个测试加载器 class 并尝试使用
URLClassLoader
- 这会让您相信您编写的代码可以正常工作。然后您可以查找问题的其他方面。
无论如何,如果以上建议有效,请告诉我。如果您无法使测试 class 正常工作,请分享代码,以便这里的其他成员可以更好地理解您正在尝试做什么。
它在 class 加载程序更改时起作用,如下所示。
URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/opt/jars/Tracking.jar") }, this.getClass().getClassLoader());
其他一切都一样...正如我所说,不添加当前 class 加载程序在 运行 在 eclipse 中时也能正常工作。