[英]Load Spring Boot Classes in ClassLoader
I need to read a Spring Boot jar and load all the clases on a ClassLoader. 我需要阅读一个Spring Boot jar并将所有clase加载到ClassLoader上。
My problem,in spring boot classes are on "/BOOT-INF/classes" directory and not on the root directory. 我的问题是,春季引导类位于“ / BOOT-INF / classes”目录中,而不位于根目录中。
Anybody knows how i can load this classes in my ClassLoader? 有人知道我如何在我的ClassLoader中加载此类吗?
I try to do this: 我尝试这样做:
private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException {
return URLClassLoader
.newInstance(new URL[] { new URL("jar:file:" + jarPath.toAbsolutePath().toString() + "!/") });
}
This load the jar, but no the classes inside /BOOT-INF/classes 这将加载jar,但/ BOOT-INF / classes中没有任何类
Investigating a bit how spring boot loads third party(Liquibase) classes, i would go like this: 研究一下Spring Boot如何加载第三方(Liquibase)类,我会像这样:
Given that you know the package name you want to load 既然您知道要加载的软件包名称
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);
}
}
Also use your class loader with loaded jar: 还要对加载的jar使用类加载器:
findAllClasses("com.package", getURLClassLoaderFromJar(pathToJar));
This variant is safe to use with Spring Boot packaged executable JARs 此变体可以安全地与Spring Boot打包的可执行JAR一起使用
I finally opted for decompress de jar on a temporary directory and create a URLClassloader with this entries: One to the root directory. 我最终选择了在临时目录上解压缩de jar并使用以下条目创建URLClassloader:一个到根目录。 One to the BOOT-INF/classes And one for every jar in BOOT-INT/lib 一个到BOOT-INF / classs,一个到每个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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.