在生产中不使用 spring-boot 类加载器是否有警告?

fla*_*ers 5 java classloader spring-boot classloading

什么

我想用jdk.internal.loader.ClassLoaders$AppClassLoaderspring-boots 代替org.springframework.boot.loader.LaunchedURLClassLoader。但是,我不确定这将如何影响 spring-boot 运行时。

为什么

我们最近在java.lang.InstantiationErrorjava 的parallelStream(). 我了解到并行流中的线程正在使用AppClassLoader,因此无法找到驻留在类加载器层次结构中LaunchedURLClassLoader的子级中的应用程序类AppClassLoader

如何

spring -boot 文档显示您可以在不使用类加载器的情况下运行解压的 spring-boot jar。这很方便地意味着应用程序类也被加载到 中AppClassLoader,从而解决了我们的问题parallelStream()

$ java -cp BOOT-INF/classes:BOOT-INF/lib/* com.example.MyApplication
Run Code Online (Sandbox Code Playgroud)

注意:这也是 Intellij IDEA 运行 spring-boot 应用程序的方式。

问题

谁知道 spring-boot 类加载器是否所做的不仅仅是启用我应该了解的可执行 jar 和 war 文件。我发现文档不够明确。在生产中不使用 spring-boot 类加载器是否安全?

Pat*_*die 1

我还遇到了间歇性问题,突然使用 AppClassLoader 而不是 LaunchedURLClassLoader(甚至在并行执行之外),导致找不到资源。

\n

最新版本的文档有一个高效部署部分,该部分表示运行解压的存档会更快。

\n
\n

某些 PaaS 实现也可能选择在运行之前解压存档。例如,Cloud Foundry 就是这样运作的。

\n
\n

知道了这一点,我可以说在生产中执行此操作绝对安全。\n我什至会说它更安全,因为它在运行时会更简单,但这是我的拙见。

\n
\n

解压 jar 文件后,您还可以通过使用其“自然”主方法运行应用程序来额外缩短启动时间 [...]:

\n
\n
$ jar -xf myapp.jar\n$ java -cp "BOOT-INF/classes:BOOT-INF/lib/*" com.example.MyApplication\n
Run Code Online (Sandbox Code Playgroud)\n

在 Windows 上,在 caspath 中替换:;

\n
> java -cp "BOOT-INF/classes;BOOT-INF/lib/*" com.example.MyApplication\n
Run Code Online (Sandbox Code Playgroud)\n

正如你所说,它方便地意味着我们摆脱了 Spring Boot 的自定义,LaunchedURLClassLoader因为所有内容都是由 加载的AppClassLoader

\n

您现在可以使用 ForkJoinPool (parallel()等),而不会出现 ClassLoader 问题:

\n
[main] Test : CCL: jdk.internal.loader.ClassLoaders$AppClassLoader@2a139a55\n[ForkJoinPool.commonPool-worker-1] Test  : CompletableFuture.runAsync CCL: jdk.internal.loader.ClassLoaders$AppClassLoader@2a139a55\n
Run Code Online (Sandbox Code Playgroud)\n
\n

警告 - 只有一个注释:

\n
\n

在 application\xe2\x80\x99s main 方法上使用 JarLauncher 具有可预测类路径顺序的额外好处。该 jar 包含一个 classpath.idx 文件,JarLauncher 在构建类路径时使用该文件。

\n
\n

这意味着使用 JarLauncher 而不是 LaunchedURLClassLoader 运行分解的存档是安全且一致的,因为您保持相同的类路径顺序。但 JarLauncher 启动了 LaunchedURLClassLoader,因此它并不能解决我们的问题。

\n

因此,在使用“自然”的 main 方法时,请注意不可预测的类路径顺序。这似乎是唯一的缺点。

\n

就我个人而言,我对类路径排序没有任何问题。

\n

读:

\n\n
\n

更进一步:

\n

看看LaunchedURLClassLoader,它扩展了URLClassLoader,并分析LaunchedURLClassLoaderTests中的测试,我可以说它只是添加了处理 JAR 资源加载和嵌套 JAR 的逻辑。过去已经通过添加“快速异常”机制修复了像#4582这样的性能问题。

\n