Spring boot WAR runs from maven, not from command line?

Viewed 13895

I checked this question, but the answer (while interesting) basically says "don't use WAR packaging" which is not an option here.

I have a Spring Boot repackaged WAR which uses embedded Tomcat (Spring Boot 1.5.3.RELEASE, embedded Tomcat 8.5.14). The repackaged app runs fine using the mvn spring-boot:run command but when I try to run it using `java -jar target\mywar.war' I get this:

java.io.FileNotFoundException: file:\C:\work\spring-boot\target\spring-boot-mywar.war!\WEB-INF\classes!\mywar.war (The filename, directory name, or volume label syntax is incorrect)

This is caused when Spring Boot tries to load the context for the "wrapped" war:

Context context = tomcat.addWebapp("/mywar", Thread.currentThread().getContextClassLoader().getResource("mywar.war").getPath());

The actual error takes place inside the embedded Tomcat class:

private URL getWebappConfigFileFromJar(File docBase, String contextName) {
    URL result = null;
    try (JarFile jar = new JarFile(docBase)) {
        JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml);
        if (entry != null) {
            result = UriUtil.buildJarUrl(docBase, Constants.ApplicationContextXml);
        }
    } catch (IOException e) {
        Logger.getLogger(getLoggerName(getHost(), contextName)).log(Level.WARNING,
                "Unable to determine web application context.xml " + docBase, e);
    }
    return result;
}

The operation new JarFile(docBase) throws the FileNotFoundException.

This works fine when the Maven spring-boot:run goal is used, so I feel that the basic structure is sound - I think there's some classpath issue or something that's keeping it from working.

Does anyone have any suggestion for duplicating the environment of spring-boot:run on the command line when using WAR packaging?

2 Answers
Related