在 ClassLoader 中加载 Spring Boot 类
Load Spring Boot Classes in ClassLoader
我需要读取 Spring 引导 jar 并将所有类加载到 ClassLoader。
我的问题,spring 启动 类 位于“/BOOT-INF/classes”目录而不是根目录。
有人知道我如何在我的 ClassLoader 中加载这个 类 吗?
我尝试这样做:
private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException {
return URLClassLoader
.newInstance(new URL[] { new URL("jar:file:" + jarPath.toAbsolutePath().toString() + "!/") });
}
这会加载 jar,但不会在 /BOOT-INF/classes
中加载 类
稍微调查一下 spring 引导如何加载第三方 (Liquibase) classes,我会这样:
假设您知道要加载的包名称
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);
}
}
也可以使用您的 class 加载器加载 jar:
findAllClasses("com.package", getURLClassLoaderFromJar(pathToJar));
此变体可以安全地与 Spring 启动打包一起使用
可执行 JAR
我最终选择在一个临时目录上解压 de jar 并使用以下条目创建一个 URLClassloader:
一到根目录。
一到 BOOT-INF/classes
BOOT-INT/lib
中的每个罐子一个
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);
}
}
我需要读取 Spring 引导 jar 并将所有类加载到 ClassLoader。
我的问题,spring 启动 类 位于“/BOOT-INF/classes”目录而不是根目录。
有人知道我如何在我的 ClassLoader 中加载这个 类 吗?
我尝试这样做:
private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException {
return URLClassLoader
.newInstance(new URL[] { new URL("jar:file:" + jarPath.toAbsolutePath().toString() + "!/") });
}
这会加载 jar,但不会在 /BOOT-INF/classes
中加载 类稍微调查一下 spring 引导如何加载第三方 (Liquibase) classes,我会这样:
假设您知道要加载的包名称
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);
}
}
也可以使用您的 class 加载器加载 jar:
findAllClasses("com.package", getURLClassLoaderFromJar(pathToJar));
此变体可以安全地与 Spring 启动打包一起使用 可执行 JAR
我最终选择在一个临时目录上解压 de jar 并使用以下条目创建一个 URLClassloader: 一到根目录。 一到 BOOT-INF/classes BOOT-INT/lib
中的每个罐子一个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);
}
}