Spring Boot Maven – Unable to package Web app as executable jar/war

I’m trying to learn how to build a Web App using Spring Boot and MVC.

I’m able to create a Spring boot application, and run it from my Eclipse by executing the main method in my SpringBootWebApplication class. It works fine and I’m able to launch my application by hitting http://localhost:8080.

Now, I want to package my application as an executable WAR or JAR (I don’t know which one is right!). To do this, I added a build plugin called spring-boot-maven-plugin in my pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.sriram</groupId>
    <artifactId>springboot</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Tomcat Embed -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <!-- To compile JSP files -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <!-- Package as an executable jar/war -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

For the record, I created this pom based on the tutorial here

When I run mvn clean package -e from my Command prompt, I get an error like the one below:

[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building springboot Maven Webapp 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for org.springframework.boot:spring-boot-maven-plugin:jar:1.5.1.RELEASE is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.890 s
[INFO] Finished at: 2017-08-01T13:03:42+05:30
[INFO] Final Memory: 8M/184M
[INFO] ------------------------------------------------------------------------
[ERROR] Plugin org.springframework.boot:spring-boot-maven-plugin:1.5.1.RELEASE or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.springframework.boot:spring-boot-maven-plugin:jar:1.5.1.RELEASE: 1 problem was encountered while building the effective model for org.springframework.boot:spring-boot-maven-plugin:[unknown-version]
[ERROR] [FATAL] Non-parseable POM C:/Users/Sriram/.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom: in epilog non whitespace content is not allowed but got r (position: END_TAG seen ...</profiles>/n</project>/nr... @946:2)  @ C:/Users/Sriram/.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom, line 946, column 2
[ERROR] -> [Help 1]
org.apache.maven.plugin.PluginResolutionException: Plugin org.springframework.boot:spring-boot-maven-plugin:1.5.1.RELEASE or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.springframework.boot:spring-boot-maven-plugin:jar:1.5.1.RELEASE
        at org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver.resolve(DefaultPluginDependenciesResolver.java:117)
        at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getPluginDescriptor(DefaultMavenPluginManager.java:181)
        at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getMojoDescriptor(DefaultMavenPluginManager.java:286)
        at org.apache.maven.plugin.DefaultBuildPluginManager.getMojoDescriptor(DefaultBuildPluginManager.java:241)
        at org.apache.maven.lifecycle.internal.DefaultLifecycleMappingDelegate.calculateLifecycleMappings(DefaultLifecycleMappingDelegate.java:110)
        at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateLifecycleMappings(DefaultLifecycleExecutionPlanCalculator.java:266)
        at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateMojoExecutions(DefaultLifecycleExecutionPlanCalculator.java:217)
        at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:127)
        at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:145)
        at org.apache.maven.lifecycle.internal.builder.BuilderCommon.resolveBuildPlan(BuilderCommon.java:96)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:110)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.springframework.boot:spring-boot-maven-plugin:jar:1.5.1.RELEASE
        at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:339)
        at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:199)
        at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(DefaultRepositorySystem.java:296)
        at org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver.resolve(DefaultPluginDependenciesResolver.java:103)
        ... 27 more
Caused by: org.apache.maven.model.building.ModelBuildingException: 1 problem was encountered while building the effective model for org.springframework.boot:spring-boot-maven-plugin:[unknown-version]
[FATAL] Non-parseable POM C:/Users/Sriram/.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom: in epilog non whitespace content is not allowed but got r (position: END_TAG seen ...</profiles>/n</project>/nr... @946:2)  @ C:/Users/Sriram/.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom, line 946, column 2

        at org.apache.maven.model.building.DefaultModelProblemCollector.newModelBuildingException(DefaultModelProblemCollector.java:197)
        at org.apache.maven.model.building.DefaultModelBuilder.readModel(DefaultModelBuilder.java:581)
        at org.apache.maven.model.building.DefaultModelBuilder.readParentExternally(DefaultModelBuilder.java:1097)
        at org.apache.maven.model.building.DefaultModelBuilder.readParent(DefaultModelBuilder.java:829)
        at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:331)
        at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:321)
        ... 30 more
[ERROR]
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException

I do not get any compilation errors from within my source. Given that my application is able to start up when I run the main method from within eclipse, why is my maven packaging not working? I could figure out the following:

Based on the stacktrace, I opened up the file C:/Users/Sriram.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom using Notepad++, and it did have some errors – I mean the XML seemed to be malformed and Notepad++ too threw a parse error.

While I can figure out this is the problem, I’mm not sure how the XML ended up as corrupt while it was automatically set up by my Maven pom.
What am I missing?

Thanks,
Sriram

You have (at least) two things to correct.

The first : your maven build fails :

[FATAL] Non-parseable POM
C:/Users/Sriram.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom:
in epilog non whitespace content is not allowed but got r (position:
END_TAG seen …/n/nr… @946:2) @
C:/Users/Sriram.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/spring-boot-parent-1.5.1.RELEASE.pom,
line 946, column 2

The cause is not your actual pom but the spring-boot-parent-1.5.1.RELEASE.pom dependency that seems corrupted.
So, first delete the C:/Users/Sriram.m2/repository/org/springframework/boot/spring-boot-parent/1.5.1.RELEASE/ folder and relaunch the build to download it.

Second problem : to create a executable jar or war, you have to use the
spring-boot:repackage goal.

From the plugin documentation :

repackage: create a jar or war file that is auto-executable. It can
replace the regular artifact or can be attached to the build lifecycle
with a separate classifier.

In your pom you don’t specify the repackage goal.
You specify just the spring-boot-maven-plugin:

<build>
    <plugins>
        <!-- Package as an executable jar/war -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

So replace it by :

<build>
    <plugins>
        <!-- Package as an executable jar/war -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>           
            <executions>
               <execution>
                <goals>
                   <goal>repackage</goal>
                </goals>
              </execution>
           </executions>
        </plugin>
   </plugins>
</build>