Spring Boot可执行JAR - 布局更改打破Classpath

Jam*_*ker 1 java spring-boot

我有一个Spring Boot应用程序,允许从类路径加载其他组件(如果它们是我的应用程序中定义的接口的子类).这在Spring Boot 1.3.8中运行得很好,但是我想升级到Spring Boot 1.4.2但是可执行JAR的新布局导致了一些问题.

当我现在在类路径上使用额外的JAR运行我的应用程序时,我得到了我正在尝试子类化的接口的ClassNotFoundException.这告诉我,虽然应用程序知道我的类在BOOT-INF中的位置,但由于它们不在标准位置,因此其他组件无法找到它们.

有谁知道如何解决这个问题?

我在spring-boot-maven-plugin中尝试了不同的布局选项,但它们似乎都没有做我想要的.

tan*_*an9 10

Spring Boot可执行jar 在运行时使用由Launcher创建的自己的ClassLoader.由System ClassLoader加载的类(由-cp类路径指定)不知道可执行jar中由子ClassLoader加载的类.因此,在您的情况下ClassNotFoundException.

JAR或者WAR布局中的可执行jar 使用简单Launcher的关注捆绑在bundle中的类.您必须PropertiesLauncher通过loader.path以任一方式指定应用程序属性来指示Spring Boot的ClassLoader加载您的类:

方法1.直接运行PropertiesLauncher类:

$ java -Dloader.path=... -cp myjar.jar org.springframework.boot.loader.PropertiesLauncher [args...]
Run Code Online (Sandbox Code Playgroud)

此命令绕过可执行jar/war中的默认Luncher(Main-Class在myjar.jar!/META-INF/MANIFEST.MF中的条目中列出).并直接调用PropertiesLauncher该类.

方法2.将PropertiesLauncher设置为默认值(使用ZIP布局)

ZIP布局,如Spring Boot文档中所述:

与JAR布局类似,使用PropertiesLauncher.

默认情况下,布局中的打包可执行文件会查找loader.*属性,因此您可以像下面这样运行它:

$ java -Dloader.path=... -jar myjar.jar [args...]
Run Code Online (Sandbox Code Playgroud)

对于Maven项目,在POM.xml中将布局设置为ZIP:

<project>
   <!-- ... -->
   <build>
      <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <configuration>
                  <layout>ZIP</layout>
              </configuration>
          </plugin>
      </plugins>
   </build>
</project>
Run Code Online (Sandbox Code Playgroud)

对于Gradle项目:

springBoot {
  layout = 'ZIP'
}
Run Code Online (Sandbox Code Playgroud)