在Java中使用反射加载已加载类的导入类
我试图从jar文件加载类。基本上,我想在jar的包中调用特定类中的方法。我在这里面临的问题是,在成功地从jar加载类之后,当我尝试实例化时,对于在我的类中导入的类,我得到了exception:ClassNotFound 下面是加载该类的类: 输入:D:\Myjar.jar,com.vendor.epbroker.vnflcmccommunicator在Java中使用反射加载已加载类的导入类,java,exception,reflection,Java,Exception,Reflection,我试图从jar文件加载类。基本上,我想在jar的包中调用特定类中的方法。我在这里面临的问题是,在成功地从jar加载类之后,当我尝试实例化时,对于在我的类中导入的类,我得到了exception:ClassNotFound 下面是加载该类的类: 输入:D:\Myjar.jar,com.vendor.epbroker.vnflcmccommunicator public Class<?> loadClass(String libPath, String pkgName) {
public Class<?> loadClass(String libPath, String pkgName) {
LogManager.getLogger().info("Adding Class");
File jarFile = null;
try {
jarFile = new File(libPath);
URL fileURL = jarFile.toURI().toURL();
String jarURL = "jar:" + fileURL + "!/";
URL urls[] = { new URL(jarURL) };
URLClassLoader ucl = new URLClassLoader(urls);
Class<?> beanClass = ucl.loadClass(pkgName);
ucl.close();
return beanClass;
} catch (Exception ex) {
LogManager.getLogger().error("Given Library: " + libPath + " or Class name: " + pkgName + " is not Valid");
LogManager.getLogger().error("Exception occurred : ", ex);
}
LogManager.getLogger().error("Class loading Error: Returning NULL");
return null;
}
遇到以下错误:
SEVERE: Servlet.service() for servlet [spring] in context with path [/vnflcm] threw exception [Handler processing failed; nested exception is java.lang.NoClassDefFoundError: com/vendor/epbroker/exception/EPBrokerException] with root cause
java.lang.ClassNotFoundException: com.vendor.epbroker.exception.EPBrokerException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
如果您有任何帮助,我们将不胜感激。在尝试使用
反射时,您必须考虑以下几点
URLClassLoader必须包含要反映到的jar的URL李>
如果所需的jar依赖于任何其他jar,则必须同时加载这些jar的url
正如@VGR指出的,您不能简单地将jar的文件路径用作URL。您可以做的一件事是:
File myJar = new File("path/to/myJar.jar");
URL myJarUrl = myJar.toURI().toURL();
一个简单的例子来说明这个问题:
让我们将您的jar称为myToolProject。比如说,在开发这个工具时,您创建了一个类,称之为JsonMaker
,它将POJO转换为JSON,您可以通过gson.jar
来实现这一点。当您构建jar时,我们称之为myjar.jar,您在清单中提到它依赖于gson
在尝试反思myjar时,您会反思jar中的每个类,直到到达JsonMaker.class
。当我们试图在这里反映时,我们注意到这里有com.google.Gson
type对象。URLClassLoader查看其数组中的URL,并尝试在某个类中查找com.google.Gson
。如果它找不到任何com.google.Gson
类,它将无法反映该类,并抛出一个ClassNotFoundException
查看以下行:
URLClassLoader ucl = new URLClassLoader(urls);
Class<?> beanClass = ucl.loadClass(pkgName);
ucl.close();
URLClassLoader ucl=新的URLClassLoader(URL);
类beanClass=ucl.loadClass(pkgName);
ucl.close();
并考虑文献:
关闭此URLClassLoader,使其不再用于加载此装入器定义的新类或资源
换句话说,只有当您真正使用了类加载器的类时,才应该关闭该类加载器。即使此时已经加载了所有必需的类,仍然有可能需要访问必需的资源。注意,有些框架有自己的反射库,需要访问类的字节码,这些字节码将像资源一样被访问
在您的特定情况下,它甚至更简单。您刚刚加载了一个类,它只触发了所需的最小类集的解析(例如direct super类),但没有其他依赖项。然后关闭类加载器,防止后续从jar文件加载任何其他类,当解析构造函数需要解析更多引用的类时,会遇到这种情况。删除字符串jarURL=…
行。URL根本不应该是“jar:”URL。只要做URL[]={fileURL}代码>@VGR这也没有帮助。执行此操作仍然会产生相同的错误。此外,com.google.gson.gson和其他软件包中的类也出现了错误。不确定如何解决此问题。您说错误发生在您尝试加载com.google.gson.gson时,但异常表示找不到com.vendor.epbroker.exception.EPBrokerException。EPBrokerException.class是否在.jar文件中?
URLClassLoader ucl = new URLClassLoader(urls);
Class<?> beanClass = ucl.loadClass(pkgName);
ucl.close();