[spring-projects/spring-boot]将运行目标的目录属性重命名为additionalClasspathElements

2024-05-08 561 views
1

大家好,

看来该spring-boot.run.directories属性不起作用,并且类加载器找不到目录中的外部 JAR:

Caused by: java.lang.NoClassDefFoundError: gattaca/character/Vincent
    at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) ~[na:na]
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]

在调试模式下运行插件时,我确实看到该目录已添加到类路径中,但类加载器似乎没有在其中搜索类。

这已经在 stackoverflow https://stackoverflow.com/questions/62389508/external-jar-class-not-found-while-run-time-in-spring-boot-maven上报告,但我无法使用提到的解决方法。如果您需要复制器,请告诉我。

谢谢!

回答

8

添加目录本身,并不意味着会拾取 JAR 文件。该属性的文件说明如下:

除了类目录之外,还应添加到类路径中的其他目录。

如果将 JAR 文件放入“classes”目录中,也不会被拾取。看看SO问题,它似乎与你所描述的无关。如果我错过了一些内容,请分享一个包含更多详细信息的复制者。

3

感谢@snicoll 的快速回复!

所以spring-boot.run.directories应该指向类!这对我来说有点误导,因为在标准 Java 中你也可以指向 JAR,并且类加载器能够处理这些......

3

到底什么是误导呢?目录和文件是两个独立的东西,Javadoc 以及属性名称非常明确地表明它是前者。

*如果您想从目录加载 JAR 文件,则需要使用标准 Java 。

3

嗨@snicoll!我可以确认指向文件而不是目录有效:

-Dspring-boot.run.directories=/path/to/jar/file/file.jar

或者正如您所提到的,在指向目录时附加一个 * 就像使用 java -cp ...

-Dspring-boot.run.directories=/path/to/jar/directory/*

再次感谢并抱歉造成噪音......

8

或者正如您所提到的,在指向目录时附加一个 * 就像使用 java -cp ...

根据记录,这两个都破坏了原始功能。此功能并不是要向类路径添加额外的 jar 文件,而是以目录的形式添加额外的类路径位置。您的第一个示例指向一个文件(不是目录),第二个示例也不是目录。

我们可能会决定限制或重新访问此功能,但这些功能都不会发挥作用,因为它从未想过。

1

啊,那太糟糕了!有时在运行时将库添加到类路径(例如provided范围依赖项)或切换 API 的实现等很有用。但也许可以通过新选项而不是这个选项来提供。谢谢!

2

目录限制对我来说有点随意。我认为允许将其他目录或 jar 添加到类路径中会更自然。为了直观起见,这需要为该属性指定一个新名称。虽然没有命令行选项,但该设置类似于 bootRun 的类路径,可以将文件和目录添加到其中。 Maven 和 Gradle 之间具有一定的对称性很有吸引力。

5

您好,请问这个问题可以吗?

2

@rafaelrc7 是的,欢迎您对其进行处理并提交拉取请求,但是,我们尚未针对 3.2 进行分支,因此我们可能无法立即合并它。

9

你好,我想确认一个细节。有人指出,这个想法是

将值直接传递给 -cp,而不转换为 File/URI/URL/File。

目前,数组中的值directories(将成为新additionalClasspathElements属性)经过上述转换,由类中的addUserDefinedDirectories()和方法完成。 addClasspath()org.springframework.boot.maven.AbstractRunMojo

由于不再需要这种转换,我正在考虑将这些值直接附加到addClasspath()使用 URL 值的现有代码旁边的方法中的类路径中getClassPathUrls()。这样可以吗?

提到的 Mojohaus/exec-maven-plugin 代码(链接在此处)对相对路径等进行了一些处理。这是可取的吗?或者应该将原始additionalClasspathElements内容附加到类路径中?

提前致谢。

5

有趣的是,Mojohaus/exec-maven-plugin 应用了额外的路径处理。我想我们希望我们能够在不需要任何处理的情况下添加字符串。请随意使用您当前的方法提交拉取请求,但我们会在合并之前对其进行修改。