Java 9, compatability issue with ClassLoader.getSystemClassLoader

后端 未结 8 1324
面向向阳花
面向向阳花 2020-11-29 09:19

The following code adds jar file to the build path, it works fine with Java 8. However, it throws exception with Java 9, the exception is related to the cast to URLClassLoad

8条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-29 09:52

    If you're just looking to read the current classpath, for example because you want to spin up another JVM with the same classpath as the current one, you can do the following:

    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)
      )
    

    By default the final fields in the $AppClassLoader class cannot be accesed via reflection, an extra flag needs to be passed to the JVM:

    --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
    

提交回复
热议问题