ClassNotFoundException 和 NoClassDefFoundError 尝试使用 java.lang.reflect 检查 Spring Boot jar 文件
我正在尝试构建一个工具,可以检查打包为 jar 的指定 Spring Boot 应用程序。我能够列出 jar 的内容,并且我能够加载和检查一些类,但其他类,最重要的是我们自己的类 - 那些构成实际应用程序代码的类 - 我无法检查并获取 ClassNotFoundException
尝试加载它们时。这些类中的许多(但不是全部)都位于 BOOT-INF/classes
中,我尝试过在提供的 URL 中使用或不使用该路径,以及使用或不使用该路径作为类名的一部分。我还收到许多 NoClassDefFoundError
异常。如果我展开 jar 文件,“丢失”的类位于 BOOT-INF/classes/
下的预期位置,
我不尝试运行该应用程序。这与 ./gradlew bootrun
配合得很好,我并没有尝试创建自定义启动器或类似的东西,这就是我能够找到的示例代码。即使是 SO 建议也都与运行和部署 Spring Boot 应用程序的问题有关。我确信原因是相似或相关的,但我不知道如何弥合差距。
我想要做的就是提取所有具有 @Value
注释的参数,并为我们的代码和任何依赖项报告这些注释的值。最终,我希望能够验证我们的 yaml 配置并报告这些文件中缺少的配置值。
清单(稍作编辑):
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.redacted.redacted.redacted.redacted.redactedApp
lication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.5.8
Specification-Version: 1.0.0
Main-Class: org.springframework.boot.loader.JarLauncher
我的类加载器是这样创建的:
final URL url = jarFile.getUrl();
final URLClassLoader urlClassLoader = LaunchedURLClassLoader.newInstance(new URL[] {
new URL(url.toString() + "BOOT-INF/classes!/"),
url,
});
我获取类名并尝试加载(未显示异常处理代码):
String name = jarEntry.getName();
int endIndex = name.lastIndexOf(".class");
String className = name.substring(0, endIndex)
.replace('/', '.').replace("BOOT-INF.classes.", "");
Class<?> loadedClass = urlClassLoader.loadClass(className);
如何解决加载这些类的问题,或者,是否有另一种方法使用 @Value
注释提取所有代码和依赖项的所有参数?
I am trying to build a tool that can inspect a specified Spring Boot application packaged as a jar. I am able to list the contents of the jar, and I am able to load and inspect some classes, but others, most importantly our own classes -- those that make up the actual application code -- I cannot inspect and get a ClassNotFoundException
when trying to load them. Many, but not all, of those classes are located in BOOT-INF/classes
and I have tried both with and without that path in the URLs provided, and with and without that as part of the class name. I also get many NoClassDefFoundError
exceptions. If I expand the jar file, the "missing" classes are located where expected under BOOT-INF/classes/
I am not trying to run the application. That works fine with ./gradlew bootrun
and I am not trying to create a custom launcher or anything like that, which is all I'm able to find for sample code. Even the SO suggestions are all related to issues running and deploying Spring Boot applications. I'm sure the causes are similar or related, but I don't know how to bridge the gap.
All I want to do is extract all the parameters that have the @Value
annotation and report the values of those annotations, for both our code and any dependencies. Ultimately I want to be able to validate our yaml configurations and report on missing configuration values that are missing from those files.
Manifest (lightly redacted):
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.redacted.redacted.redacted.redacted.redactedApp
lication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.5.8
Specification-Version: 1.0.0
Main-Class: org.springframework.boot.loader.JarLauncher
My class loader is created like this:
final URL url = jarFile.getUrl();
final URLClassLoader urlClassLoader = LaunchedURLClassLoader.newInstance(new URL[] {
new URL(url.toString() + "BOOT-INF/classes!/"),
url,
});
I get the class name and try to load (exception handling code not shown):
String name = jarEntry.getName();
int endIndex = name.lastIndexOf(".class");
String className = name.substring(0, endIndex)
.replace('/', '.').replace("BOOT-INF.classes.", "");
Class<?> loadedClass = urlClassLoader.loadClass(className);
How can I fix the problem loading these classes, or, alternatively, is there another way to extract all parameters with the @Value
annotation, for all code and dependencies?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论