Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在类加载器中加载Spring引导类_Java_Spring_Spring Boot_Classloader - Fatal编程技术网

Java 在类加载器中加载Spring引导类

Java 在类加载器中加载Spring引导类,java,spring,spring-boot,classloader,Java,Spring,Spring Boot,Classloader,我需要阅读一个Spring引导jar并将所有类加载到一个类加载器上 我的问题是,在spring中,引导类位于“/boot-INF/classes”目录,而不是根目录 有人知道如何在类加载器中加载这些类吗 我尝试这样做: private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException { return URLClassLoader .

我需要阅读一个Spring引导jar并将所有类加载到一个类加载器上

我的问题是,在spring中,引导类位于“/boot-INF/classes”目录,而不是根目录

有人知道如何在类加载器中加载这些类吗

我尝试这样做:

private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException {
        return URLClassLoader
                .newInstance(new URL[] { new URL("jar:file:" + jarPath.toAbsolutePath().toString() + "!/") });
}

这会加载jar,但不会加载/BOOT-INF/classes中的类

研究一下spring BOOT如何加载第三方(Liquibase)类,我会这样做:

假设您知道要加载的包名

Resource[] scan(ClassLoader loader, String packageName) throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(
                loader);
        String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                + ClassUtils.convertClassNameToResourcePath(packageName) + "/**/*.class";
        Resource[] resources = resolver.getResources(pattern);
        return resources;
    }


void findAllClasses(String packageName, ClassLoader loader) throws ClassNotFoundException {
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(
                loader);
        try {
            Resource[] resources = scan(loader, packageName);
            for (Resource resource : resources) {
                MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
                ClassUtils.forName(reader.getClassMetadata().getClassName(), loader)
            }
        } catch (IOException ex) {
            throw new IllegalStateException(ex);
        }
    }
还可以将类加载器与已加载的jar一起使用:

findallclass(“com.package”,getURLClassLoaderFromJar(pathToJar))

此变体可以安全地与Spring Boot一起使用
可执行jar

我最终选择在临时目录上解压de jar,并使用以下条目创建URLClassloader: 一个到根目录。 一个到BOOT-INF/classes BOOT-INT/lib中的每个jar对应一个

Path warDirectory = decompressWar(absolutePathFile);

File rootDir = new File(warDirectory.toAbsolutePath().toString());
File springBootDir = new File(warDirectory.toAbsolutePath().toString() + "/BOOT-INF/classes/");

List<URL> listaURL = new ArrayList<URL>();
listaURL.add(rootDir.toURI().toURL());
listaURL.add(springBootDir.toURI().toURL());

//This scan the BOOT-INF/lib folder and return a List<URL> with all the libraries.
listaURL.addAll(getURLfromSpringBootJar(warDirectory));


URL[] urls = new URL[listaURL.size()];
urls = listaURL.toArray(urls);
cl = new URLClassLoader(urls);

//This explore the JAR and load all the .class fulies to get the className.
resultClassesBean = loadJars(Collections.singletonList(pathJarFile), cl);

if(resultClassesBean != null && resultClassesBean.getListResultClasses() != null && !resultClassesBean.getListResultClasses().isEmpty()) {
    for(String clazz : resultClassesBean.getListResultClasses()) {
        cl.loadClass(clazz);
    }
}
Path-warddirectory=decompressWar(绝对路径文件);
File rootDir=新文件(warddirectory.toabsolutionpath().toString());
File springBootDir=新文件(warddirectory.toabsolutionpath().toString()+“/BOOT-INF/classes/”;
List listaul=new ArrayList();
add(rootDir.toURI().toul());
add(springBootDir.toURI().toul());
//这将扫描BOOT-INF/lib文件夹并返回包含所有库的列表。
addAll(getURLfromSpringBootJar(warddirectory));
URL[]URL=新URL[listaURL.size()];
URL=listaURL.toArray(URL);
cl=新的URLClassLoader(URL);
//这将探索JAR并加载所有.class文件以获得类名。
resultClassBean=loadJars(Collections.singletonList(pathJarFile),cl);
如果(ResultClassBean!=null&&ResultClassBean.getListResultClasses()!=null&&ResultClassBean.getListResultClasses().isEmpty()){
对于(字符串clazz:ResultClassBean.getListResultClasses()){
cl.loadClass(clazz);
}
}

已编辑添加信息。请尝试此功能。谢谢,我正在尝试此功能。仅使用根目录上的类。如果类位于目录中,则抛出ClassNotFoundExceptionTanks,但我不喜欢使用SPRING或第三方依赖项。