在运行时修改类路径 - 控制类加载顺序

发布于 2024-10-17 05:05:36 字数 598 浏览 3 评论 0原文

是否可以在运行时控制加载类的顺序?例如:我有类 SomeClass,它位于两个 jaras 中:SomeLibrary-1.0.jar 和 SomeLibrary-2.0.jar。该类有静态方法 getVersion(),它返回 SomeLibrary 的当前版本。我使用此处找到的解决方案在运行时修改类路径。现在,当我运行代码时:

public static void main(String[] args) {
    ClassPathHacker.addFile("SomeLibrary-1.0.jar");
    ClassPathHacker.addFile("SomeLibrary-2.0.jar");
    System.out.println(SomeClass.getVersion());
}

我希望看到输出2.0,但实际上是1.0。这是因为类加载器使用在类路径中找到的第一个类。是否可以控制加载类的排序或“覆盖”已加载的类?

Is it possible to controll order of loaded classes at runtime? For example: I have class SomeClass which is in two jaras: SomeLibrary-1.0.jar and SomeLibrary-2.0.jar. The class have static method getVersion() which returns current version of SomeLibrary. I use solution found here to modify classpath at runtime. Now, when I run the code:

public static void main(String[] args) {
    ClassPathHacker.addFile("SomeLibrary-1.0.jar");
    ClassPathHacker.addFile("SomeLibrary-2.0.jar");
    System.out.println(SomeClass.getVersion());
}

I expect to see output 2.0 but there is 1.0 instead. This is because class loader use first class found in the class path. Is it possible to control oreder of loaded classes or 'overwrite' class already loaded?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只怪假的太真实 2024-10-24 05:05:36

您有同一个 JAR 的两个版本,您需要使用不同的 ClassLoader 实例。在这种情况下,破解 SystemClassLoader 对您没有帮助。

例如,您可以将每个 jar 加载到它自己的 URLClassLoader 实例中:

URLClassLoader ucl1 = new URLClassLoader(new URL[] { new URL("SomeLibrary-1.0.jar") });
URLClassLoader ucl2 = new URLClassLoader(new URL[] { new URL("SomeLibrary-2.0.jar") });

Class<?> cl1 = ucl1.loadClass("org.example.SomeClass");
Class<?> cl2 = ucl2.loadClass("org.example.SomeClass");

Method m1 = cl1.getMethod("getVersion");
System.out.println("v1: " + m1.invoke(cl1));
Method m2 = cl2.getMethod("getVersion");
System.out.println("v2: " + m2.invoke(cl1));

You you have two versions of the same JAR you need to use different ClassLoader instances. hacking the SystemClassLoader does not help you in that case.

For example you can load each jar in it's own URLClassLoader instance:

URLClassLoader ucl1 = new URLClassLoader(new URL[] { new URL("SomeLibrary-1.0.jar") });
URLClassLoader ucl2 = new URLClassLoader(new URL[] { new URL("SomeLibrary-2.0.jar") });

Class<?> cl1 = ucl1.loadClass("org.example.SomeClass");
Class<?> cl2 = ucl2.loadClass("org.example.SomeClass");

Method m1 = cl1.getMethod("getVersion");
System.out.println("v1: " + m1.invoke(cl1));
Method m2 = cl2.getMethod("getVersion");
System.out.println("v2: " + m2.invoke(cl1));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文