最近做了一个动态加载外部jar包,最终使用的类加载器是sun.misc.Launcher$AppClassLoader,这些类中依赖的一些class在工程中本来就存在,使用的是LaunchedURLClassLoader 。       这两个加载器都是URLClassLoader的子类,问题是外部jar需要的类显然无法从LaunchedURLClassLoader中获取,一直报错“java.lang.ClassNotFoundException”。在ide中运行正常,使用的都是sun.misc.Launcher$AppClassLoader。       有什么方法能指定类加载器为LaunchedURLClassLoader吗?这个是springboot打jar包后才有的,项目中并不存在

解决方案 »

  1.   

    摸索出来了,加载外部jar时不使用默认的classloader。因为当前运行类是使用的LaunchedURLClassLoader,所以直接通过当前类获取classloader,再用其去加载外部jar就可以了。
      

  2.   

            sun.misc.Launcher$AppClassLoader 加载的路径是 “java.class.path”。根据双亲委派机制,LaunchedURLClassLoader 为其子类,应该是能在class.path 中找到相应的类的。
            问题就在这里了,“java.class.path”为应用运行的环境路径,传统应用是jre环境及应用路径,但是springboot 则为jar路径。 
            sun.misc.Launcher$AppClassLoader 显然不会去加载jar中的jar包。即springboot应用中的lib包下面的jar由其自定义的LaunchedURLClassLoader来完成加载。这样在使用AppClassLoader来加载外部类,其中引用了lib下的类,它是无法找到下级ClassLoader中的类的,也就是java.lang.ClassNotFoundException”