3

I have googled about this problem, but I'm not finding anything for this case. I found lots of "how to deploy Spring Boot WAR to Tomcat" but nothing about wrapping an existing Tomcat WAR with Spring Boot.

I'm trying to wrap an existing WAR with a Spring Boot "wrapper" so that the existing code base doesn't have to be reconfigured. This solution doesn't work because it depends on the WAR being available at an absolute location, whereas we are trying to package the "application" WAR inside the Spring Boot WAR. We can then add the context for the WAR like this:

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

This is almost working. I'm having a problem with one specific issue. When the existing WAR file is dropped into the Spring Boot project, it gets dropped into /WEB-INF/lib-provided instead of /WEB-INF/classes. I can't find a way to get the embedded Tomcat to add a WAR file from this location. The ClassLoader won't load it because it's not under WEB-INF/classes.

Is there a slick way (or any way) of grabbing this WAR from /WEB-INF/lib-provided?

Community
  • 1
  • 1
user1071914
  • 3,295
  • 11
  • 50
  • 76
  • Is your goal to make the WAR an embedded Tomcat application and you are using Spring Boot to achieve it, or do you want to use Spring Boot to its fullest? I am not sure if you can leverage the benefits of Spring Boot without reconfiguring your application to use Spring Boot. – qtips May 09 '17 at 20:02
  • Our brief is to make the existing application into a Spring Boot application with as little change as possible. Ideally we would not touch the existing app at all, just wrap it in a Spring Boot shell and make it executable without a separate Tomcat instance. I'm sure there's much more Spring Boot can do, but we have not been tasked with that. – user1071914 May 09 '17 at 22:48
  • What is the purpose of using Spring Boot in your case? I understand that your task is to simply start using Spring Boot as quickly as possbile. I am asking in case your purpose can be achieved by some other and simpler way, e.g. creating a Main class that embeds your application into a tomcat standalone server. Also, it may be very simple to start using Spring Boot too, sometimes you only need to change your pom and create a Main class. – qtips May 10 '17 at 11:57
  • Our app is a legacy app and we've been ordered not to touch it, not even to update the dependencies. We may eventually wind up modifying the app itself if this "wrapper" concept simply can't be done. – user1071914 May 10 '17 at 16:26

1 Answers1

2

For anyone else that needs to do this, the answer is to use the maven-dependency-plugin and set the spring-boot-maven-plugin to exclude the WAR file from the resources (otherwise you get two copies of the WAR included in your Spring Boot WAR):

        <!-- include your WAR as a resource instead of a dependency -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <excludeTransitive>true</excludeTransitive>
                        <includeArtifactIds>my-war-name-here</includeArtifactIds>
                        <stripVersion>true</stripVersion>
                        <outputDirectory>${project.basedir}/src/main/resources</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>


        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>1.5.3.RELEASE</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <!-- Don't copy the war as a dependency, it's included as a resource -->
                        <excludeArtifactIds>my-war-name-here</excludeArtifactIds>
                    </configuration>
                </execution>
            </executions>
        </plugin>
user1071914
  • 3,295
  • 11
  • 50
  • 76