如何将外部“war”文件加载到spring boot的嵌入式tomcat服务器中

时间:2016-04-02 12:52:25

标签: java spring tomcat spring-boot war

我正在尝试将“war”文件加载到Spring引导的嵌入式tomcat服务器中。 为此,我找到了这个答案: Spring Boot: How to add another WAR files to the embedded tomcat?

但是在我这样做之后,我发现在这个问题上已经提出了同样的错误: Deploying existing war with embedded Tomcat但是 没有一个满意的答案。

注意:我知道它可以被视为一个重复的问题(我把链接),但当时没有足够的声誉来添加评论,或者能够联系作者私有,我已经看到需要重复这个问题,希望得到一些不同的答案。

特别是我尝试加载在spring boot项目的“resources / war /”文件夹中分配的Sesame war文件。

我的SpringBoot应用程序:

@SpringBootApplication
@ComponentScan("com.github.p4535992.mvc")
public class JspDemoApplication extends SpringBootServletInitializer implements WebApplicationInitializer{

public static void main(String[] args) {
    SpringApplication.run(JspDemoApplication.class, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(JspDemoApplication.class);
}

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    SpringApplication.run(JspDemoApplication.class);
}

/*
 * https://stackoverflow.com/questions/31374726/spring-boot-how-to-add-another-war-files-to-the-embedded-tomcat
 * @return the {@link TomcatEmbeddedServletContainerFactory}.
 */
@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory() {
        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
            try {
                //tomcat.addUser("tomcat", "tomcat");
                //tomcat.addRole("tomcat", "manager-gui");
                String webappDirLocation = System.getProperty("user.dir")+"/src/main/resources/war/";
                //When the spring boot application is made of fat jar(=executable jar),
                // the above code is not enough             
                Context context1 = tomcat.addWebapp("/sesame", new
                        File(webappDirLocation+"openrdf-sesame.war").getAbsolutePath());
                Context context2 =  tomcat.addWebapp("/workbench",new
                        File(webappDirLocation+"openrdf-workbench.war").getAbsolutePath());
                WebappLoader loader = new WebappLoader(Thread.currentThread().getContextClassLoader());
                context1.setLoader(loader);
                context2.setLoader(loader);

            } catch (ServletException ex) {
                throw new IllegalStateException("Failed to add webapp", ex);
            }
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }

    };
}
}

我的旧例外:old_exception

更新

注意:我在Windows上工作只是为了澄清。

  1. 在application.properties文件中添加参数: server.tomcat.basedir = $ {java.io.tmpdir}
  2. 设置JAVA_OPTIONS: -Djava.io.tmpdir = C:\ Users \ Utente \ Desktop \ path \ springMVC12 \ Temp
  3. 在“Temp”目录中手动创建目录“sesame”“workbench”(有关详细信息或其他方式,请参阅OrangeDog的评论)< / LI>
  4. 使用@Configuration Spring Annotation创建一个AppConfig.java类,将JspDemoApplication.java中的方法“EmbeddedServletContainerFactory”剪切并粘贴到AppConfig.java。
  5. 现在没有抛出异常,但是当我尝试在地址上调用webapp时 http://localhost:8081/openrdf-sesamehttp://localhost:8081/sesame,我收到错误404资源未找到。

    e.g。 “status”:404,“error”:“Not Found”,“message”:“没有可用消息”

    所以现在似乎加载了war文件,但我必须错过网络应用程序的http网址集。

    更新2 Spring Boot的新Application.java:

    @SpringBootApplication
    @ComponentScan("com.github.p4535992.mvc")
    
    public class MainApp extends SpringBootServletInitializer implements WebApplicationInitializer{
    
    public static void main(String[] args) {
        SpringApplication.run(MainApp.class, args);
    }
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MainApp.class);
    }
    
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //com.github.p4535992.mvc.component.ScheduledTasks --> Work
        SpringApplication.run(MainApp.class);
    }
    
    @Bean
    public EmbeddedServletContainerFactory servletContainerFactory() {
        return new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
                try {
                    String webappDirLocation = "src/main/resources/war/";
                    tomcat.addWebapp("/sesame", new
                            File(webappDirLocation+"openrdf-sesame.war").getAbsolutePath());
                    tomcat.addWebapp("/workbench",new
                            File(webappDirLocation+"openrdf-workbench.war").getAbsolutePath());
                } catch (ServletException ex) {
                    throw new IllegalStateException("Failed to add webapp", ex);
                }
                return super.getTomcatEmbeddedServletContainer(tomcat);
            }
    
        };
    }
    }
    

    我有新的例外:

    2016-04-09_10:25:01.998 [Tomcat-startStop-1] ERROR org.apache.catalina.core.ContainerBase - A child container failed during start
    java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:871)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
    ... 6 common frames omitted
    Caused by: java.lang.IllegalStateException: java.lang.NullPointerException
    at org.springframework.boot.context.embedded.tomcat.TomcatResources$Tomcat7Resources.addJar(TomcatResources.java:125)
    at org.springframework.boot.context.embedded.tomcat.TomcatResources.addClasspathResources(TomcatResources.java:63)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory$StoreMergedWebXmlListener.onStart(TomcatEmbeddedServletContainerFactory.java:746)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory$StoreMergedWebXmlListener.lifecycleEvent(TomcatEmbeddedServletContainerFactory.java:737)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5154)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    ... 6 common frames omitted
    Caused by: java.lang.NullPointerException: null
    at org.springframework.boot.context.embedded.tomcat.TomcatResources$Tomcat7Resources.addJar(TomcatResources.java:122)
    ... 13 common frames omitted
    2016-04-09_10:06:32.378 [localhost-startStop-1] ERROR o.a.c.c.ContainerBase.[Tomcat].[localhost].[/sesame] - Servlet [jsp] in web application [/sesame] threw load() exception
    java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:518)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:499)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1102)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1038)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4997)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5289)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    2016-04-09_10:06:32.568 [localhost-startStop-1] ERROR o.a.c.c.C.[Tomcat].[localhost].[/workbench] - Servlet [jsp] in web application [/workbench] threw load() exception
    java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:518)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:499)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1102)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1038)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4997)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5289)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    

    我尝试解决添加maven依赖项的问题,但它不起作用:

     <!-- Support for add war to the project -->
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>9.0.0.M4</version>
        </dependency>
        <!-- https://stackoverflow.com/questions/4501829/unable-to-load-class-for-jsp -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.2-b02</version>
            <scope>provided</scope>
        </dependency>
    

    欢迎任何帮助。

1 个答案:

答案 0 :(得分:1)

  

我发现在这个问题上已经提出了同样的错误:使用嵌入式Tomcat部署现有的战争但没有令人满意的答案。

因为这样的配置对Spring Boot没有意义。 Spring Boot有两个选项:

  1. WAR,部署在共享和托管的servlet容器上
  2. fat JAR,您的单个应用程序将在单个嵌入式servlet容器上运行
  3. Read this section of Spring Boot docs了解更多信息。

    另请注意,您所指的问题与Spring / Spring Boot无关。