URLClassLoader 抛出“找不到类定义”异常
我有 3 个 Java 项目 A、B 和 C。 B 就像 A 的附加组件。A 和 B 的某些类都依赖于项目 C。
现在在项目 A 中,当我使用 URLClassLoader 时,如下所示:
URLClassLoader ucl = new URLClassLoader(urls); //urls are paths to some classes in B
现在,当使用这些 ucl 时,当我调用 B 中的某些方法时,它会给我未找到类定义异常。这是针对 C 类的。
现在,当我按如下方式使用 ClassLoader 时:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader ucl = new URLClassLoader(urls, classLoader);
当我调用 B 中的方法时,效果很好。 我的问题:
1)当我用第一种方法时,正在使用哪个类加载器?我阅读了 JavaDocs,但找不到任何可以解释的内容。
2)有没有办法获得一个特定于项目B的类加载器,我可以以某种方式使用它,这样我就不会遇到任何依赖问题?
感谢您的任何帮助。
I have 3 Java projects A, B and C.
B is like an add-on to A. A and B both depend on project C for some classes.
Now in project A when I use a URLClassLoader as follows:
URLClassLoader ucl = new URLClassLoader(urls); //urls are paths to some classes in B
Now when using these ucl, when I call some methods in B, it gives me No Class Definition found exception. This is for a class which is C.
Now when I use the ClassLoader as follows:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader ucl = new URLClassLoader(urls, classLoader);
This works fine when I call the methods in B.
My Question:
1) When I do it the first way, which ClassLoader is being used? I read the JavaDocs, but couldn't find anything that I could explain myself to.
2) Is there a way to get a ClassLoader which will be specific to project B, that I can use somehow, so that I won't hit any dependency issues?
Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
默认类加载器是系统类加载器(加载类路径上的类)。
如果您使用特定的类加载器加载了 B 中的类,请使用该实例。否则
someTypeInB.getClass().getClassLoader()
将作为黑客。(注意:使用
URLClassLoader.newInstance
通常优于new URLClassLoader
,因为它添加了与不受信任的代码一起使用所需的安全措施(尽管并不充分)。还可以使用线程上下文类加载器通常是一个坏主意 - 您引入了对本地代码段的依赖关系,但是线程的设置和使用[可能没有任何一致的策略应用于它]。)The default class loader is the system class loader (loads the classes on the classpath).
If you loaded classes in B with a specific class loader, use that instance. Otherwise
someTypeInB.getClass().getClassLoader()
will do as a hack.(Note: Using
URLClassLoader.newInstance
is generally preferable tonew URLClassLoader
, as it adds in security measures necessary (though not really sufficient) for use with untrusted code. Also using the thread context class loader is generally a bad idea - you introduce a dependency upon the local piece of code to however threads are setup and used [which probably doesn't have any coherent policy applied to it anyway].)当您使用第一个 URLClassLoader 时,该 URLClassLoader 仅使用 B 的路径进行初始化,那么如果 B 中的某些内容需要解析 C 中的某些内容才能加载,则会出现问题。通过使用第二种形式,您是在说“如果您在这里找不到所需的内容,请查看“父”类加载器。”这样C就得到了解决,皆大欢喜。
(要知道,唯一可以在不引用其他类的情况下加载的类是 Object —— 即使这是一个延伸。这不仅仅是你需要引用该类的超类 —— 至少基础 JDK 中的对象可以通过即使没有父 CL,系统类加载器也会这样做 - 但如果您调用另一个类的任何方法或操作指向另一个类的指针或任何此类事物,您需要解析该引用的类。)
When you use your first URLClassLoader, the one initialized only with a path for B, then if something in B needs to resolve something in C in order to load, it will come up short. By using the second form you're saying "If you don't find what you need here, look in the 'parent' class loader." This allows C to be resolved and everyone's happy.
(Understand that the only class that can load without referencing other classes is Object -- and even that's a stretch. It's not just that you need to reference the class's superclass -- objects in the base JDK, at least, can be referenced through the system class loader even when there is no parent CL -- but if you call any method of another class or manipulate pointers to another class or any such thing you need to resolve that referenced class.)