我可以使用PropertiesLauncher启动Spring Boot WAR吗?

时间:2015-11-27 11:15:47

标签: spring-boot

我将Spring Boot 1.2应用程序打包为WAR,因为我需要能够在应用服务器中部署该应用程序。

我还想配置一个外部路径,它将包含要添加到类路径的jar。阅读Launcher documentation后,我将构建配置为使用PropertiesLauncher

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    ...
    <layout>ZIP</layout>
  </configuration>
</plugin>

我尝试使用此附加系统属性的各种组合启动应用程序:-Dloader.path=lib/,lib-provided/,WEB-INF/classes,<my additional path>

但我总是最终得到这个错误:

java.lang.IllegalArgumentException: Invalid source folder C:\<path to my war>\<my war>.war
    at org.springframework.boot.loader.archive.ExplodedArchive.<init> ExplodedArchive.java:78)
    at org.springframework.boot.loader.archive.ExplodedArchive.<init>(ExplodedArchive.java:66)
    at org.springframework.boot.loader.PropertiesLauncher.addParentClassLoaderEntries(PropertiesLauncher.java:530)
    at org.springframework.boot.loader.PropertiesLauncher.getClassPathArchives(PropertiesLauncher.java:451)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:60)
    at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:609)

我查看了源代码,似乎PropertiesLauncher只能处理jar档案(以&#34; .jar&#34;或&#34; .zip&#34;结尾)和&#34结束爆炸档案&#34; (不以前者结束)

有可能实现我想要的吗?我做错了吗?

如果不可能,有哪种替代方案?

3 个答案:

答案 0 :(得分:1)

在Spring Boot 1.2中,PropertiesLauncher.jar.zip文件作为“jar档案”处理,将其他所有文件作为“展开的档案”(解压缩的jar)处理。它无法正确处理.war

这是我找到的替代方案:

我最终切换回常规战争启动器,我设法配置一个文件夹,使用SpringApplicationRunListener(例如简洁的伪代码)将jar内容添加到类路径中:

public class ClasspathExtender implements SpringApplicationRunListener {

    public void contextPrepared(ConfigurableApplicationContext context) {

        // read jars folder path from environment
        String path = context.getEnvironment().getProperty("my.jars-folder");

        // enumerate jars in the folder
        File[] files = new File(path).listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) { return name.endsWith(".jar"); }
        });

        URL[] urls = // convert files array to urls array

        // create a new classloader which contains the jars...   
        ClassLoader extendedClassloader = new URLClassLoader(urls, context.getClassLoader());

        // and replace the context's classloader
        ((DefaultResourceLoader) context).setClassLoader(extendedClassloader);
    }

    // other methods are empty
}

通过在META-INF/spring.factories文件中声明它来实现此侦听器:

org.springframework.boot.SpringApplicationRunListener=my.ClasspathExtender

答案 1 :(得分:1)

如果有人在这里结束,这可能会有用:

java -cp yourSpringBootWebApp.war -Dloader.path=yourSpringBootWebApp.war!/WEB-INF/classes/,yourSpringBootWebApp.war!/WEB-INF/,externalLib.jar org.springframework.boot.loader.PropertiesLauncher

(Spring-Boot 1.5.9)

https://docs.spring.io/spring-boot/docs/1.5.x/reference/html/executable-jar.html#executable-jar-launching

答案 2 :(得分:-1)

这对我有用(Spring Boot 1.3.2)

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    ...
    <layout>WAR</layout>
  </configuration>
</plugin>