首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java9,与ClassLoader.getSystemClassLoader的兼容性问题

Java9,与ClassLoader.getSystemClassLoader的兼容性问题
EN

Stack Overflow用户
提问于 2017-10-12 01:51:49
回答 4查看 15.6K关注 0票数 18

下面的代码将jar文件添加到构建路径,它在Java8上工作得很好。但是,它在Java9上抛出了异常,该异常与URLClassLoader的强制转换有关。有什么办法可以解决这个问题吗?最优的解决方案将对其进行编辑,使其同时适用于Java 8和9。

代码语言:javascript
复制
private static int AddtoBuildPath(File f) {
    try {
        URI u = f.toURI();
        URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Class<URLClassLoader> urlClass = URLClassLoader.class;
        Method method = urlClass.getDeclaredMethod("addURL", URL.class);
        method.setAccessible(true);
        method.invoke(urlClassLoader, u.toURL());
    } catch (NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException | MalformedURLException | IllegalAccessException ex) {
        return 1;
    }

    return 0;
}
EN

回答 4

Stack Overflow用户

发布于 2017-10-13 15:06:18

你遇到了这样一个事实:the system class loader is no longer a URLClassLoader。正如ClassLoader::getSystemClassLoader的返回类型所指出的,这是一个实现细节,尽管这是一个不可忽略的代码量所依赖的细节。

从注释判断,您正在寻找一种在运行时动态加载类的方法。作为Alan Bateman points out,这在Java9中不能通过附加到类路径来完成。

相反,您应该考虑为此创建一个新的类加载器。这还有一个额外的好处,那就是您将能够删除新类,因为它们没有加载到应用程序类加载器中。如果您正在针对Java9进行编译,那么您应该阅读layers -它们为您提供了一个干净的抽象来加载一个全新的模块图。

票数 10
EN

Stack Overflow用户

发布于 2019-05-04 01:51:18

如果您只是希望读取当前的类路径,例如,因为您想使用与当前JVM相同的类路径启动另一个JVM,则可以执行以下操作:

代码语言:javascript
复制
object ClassloaderHelper {
  def getURLs(classloader: ClassLoader) = {
    // jdk9+ need to use reflection
    val clazz = classloader.getClass

    val field = clazz.getDeclaredField("ucp")
    field.setAccessible(true)
    val value = field.get(classloader)

    value.asInstanceOf[URLClassPath].getURLs
  }
}

val classpath =
  (
    // jdk8
    // ClassLoader.getSystemClassLoader.asInstanceOf[URLClassLoader].getURLs ++
    // getClass.getClassLoader.asInstanceOf[URLClassLoader].getURLs

    // jdk9+
    ClassloaderHelper.getURLs(ClassLoader.getSystemClassLoader) ++
    ClassloaderHelper.getURLs(getClass.getClassLoader)
  )

默认情况下,$AppClassLoader类中的最后一个字段不能通过反射访问,需要向JVM传递一个额外的标志:

代码语言:javascript
复制
--add-opens java.base/jdk.internal.loader=ALL-UNNAMED
票数 4
EN

Stack Overflow用户

发布于 2019-09-30 00:40:35

我找到了这个,并为我工作。

String pathSeparator = Syste .getProperty("path.separator");String[] classPathEntries = System.getProperty("java.class.path") .split(pathSeparator);

来自网站https://blog.codefx.org/java/java-11-migration-guide/#Casting-To-URL-Class-Loader

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46694600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档