无法在 Linux 服务器上运行的 tomcat 上启动战争应用程序

Posted

技术标签:

【中文标题】无法在 Linux 服务器上运行的 tomcat 上启动战争应用程序【英文标题】:Can't start war application on tomcat running on Linux server 【发布时间】:2015-10-03 05:15:54 【问题描述】:

我无法在 tomcat 7 上启动应用程序。我已将它部署在 tomcat 上,但它不起作用(在 Linux 服务器上),但我可以在 Windows 上从 eclipse 运行它。这是错误:

Jul 12, 2015 2:48:16 PM org.apache.catalina.core.ContainerBase addChildInternal
SEVERE: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:672)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1862)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at cz.prosvaly.configuration.AppInitializer.onStartup(AppInitializer.java:39)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5479)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 10 more

Jul 12, 2015 2:48:16 PM org.apache.catalina.startup.HostConfig deployDescriptor
SEVERE: Error deploying configuration descriptor /etc/tomcat7/Catalina/localhost/ROOT.xml
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:904)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:672)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1862)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

这里是 AppInitializer

    package cz.prosvaly.configuration;

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

public class AppInitializer implements WebApplicationInitializer 

    public void onStartup(ServletContext container) throws ServletException 

        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(AppConfig.class);
        ctx.setServletContext(container);

        container.addListener(new ContextLoaderListener(ctx));

        ServletRegistration.Dynamic servlet = container.addServlet(
                "dispatcher", new DispatcherServlet(ctx));

        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");

        FilterRegistration.Dynamic fr = container.addFilter("encodingFilter",
                new CharacterEncodingFilter());
        fr.setInitParameter("encoding", "UTF-8");
        fr.setInitParameter("forceEncoding", "true");
        fr.addMappingForUrlPatterns(null, true, "/*");

        FilterRegistration.Dynamic filter = container.addFilter("springSecurityFilterChain",
                new DelegatingFilterProxy());
        filter.addMappingForUrlPatterns(null, true, "/*");


    


错误在这一行:

filter.addMappingForUrlPatterns(null, true, "/*");

我的绒球

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <modelVersion>4.0.0</modelVersion>
    <groupId>cz.prosvaly</groupId>
    <artifactId>prosvaly</artifactId>
    <packaging>war</packaging>
    <version>1.0.0</version>
    <name>Prosvaly.cz</name>

    <properties>
        <springframework.version>4.1.6.RELEASE</springframework.version>
        <org.springframework.security.version>4.0.1.RELEASE</org.springframework.security.version>
        <hibernate.version>4.3.6.Final</hibernate.version>
        <mysql.version>5.1.31</mysql.version>
        <joda-time.version>2.3</joda-time.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.7</version>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>$org.springframework.security.version</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>$org.springframework.security.version</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>1.8.6</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.13</version>
        </dependency>
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.7</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.5.0-b01</version>
        </dependency>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>$springframework.version</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>$springframework.version</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>$springframework.version</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>$springframework.version</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>$springframework.version</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>$hibernate.version</version>
        </dependency>

        <!-- jsr303 validation -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.2.Final</version>
        </dependency>

        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>$mysql.version</version>
        </dependency>

        <!-- Joda-Time -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>$joda-time.version</version>
        </dependency>

        <!-- To map JodaTime with database type -->
        <dependency>
            <groupId>org.jadira.usertype</groupId>
            <artifactId>usertype.core</artifactId>
            <version>3.0.0.CR1</version>
        </dependency>

        <!-- Servlet+JSP+JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- Apache Commons Upload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <warSourceDirectory>src/main/webapp</warSourceDirectory>
                        <warName>prosvaly</warName>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <finalName>prosvaly</finalName>
    </build>
</project>

@Configuration
    @EnableWebMvc
    @Import( SecurityConfig.class )
    @ComponentScan(basePackages = "cz.prosvaly")
    public class AppConfig 

        @Bean
        public ViewResolver viewResolver() 
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setViewClass(JstlView.class);
            viewResolver.setPrefix("/WEB-INF/views/");
            viewResolver.setSuffix(".jsp");

            return viewResolver;
        

        @Bean
        public MessageSource messageSource() 
            ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
            messageSource.setBasename("messages");
            return messageSource;
        

        @Bean(name="multipartResolver")
        public CommonsMultipartResolver multipartResolver()
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
            multipartResolver.setMaxUploadSize(10000000);
            return multipartResolver;
        



    

调度程序配置:

@Configuration
public class DispatcherConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
//        registry.addResourceHandler("/css/**").addResourceLocations("/resources/css/");
//        registry.addResourceHandler("/html/**").addResourceLocations("/html/");
//        registry.addResourceHandler("/images/**").addResourceLocations("/images/");   
        

春季安全

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    DataSource dataSource;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
      auth.jdbcAuthentication().dataSource(dataSource).
      usersByUsernameQuery("select username,password, enabled from admin where username=?").
      authoritiesByUsernameQuery("select username, role from user_roles where username =?  ")
      .passwordEncoder(new Md5PasswordEncoder());
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

      http.authorizeRequests()
       .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
       .and().formLogin()
       .loginPage("/login").defaultSuccessUrl("/admin/goods").failureUrl("/login?error")
            .usernameParameter("username").passwordParameter("password")        
       .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login?logout")
       .and().csrf(); 
    


有人可以帮帮我吗?

【问题讨论】:

你确定这是java文件吗?您的错误在第 39 行,代码只有 30 行。 是的,因为该类在开始时有导入 - 这就是我添加错误行的原因 - 现在我更新了我的问题并添加了所有带有导入的类 【参考方案1】:

您能否发布您的 Spring 安全初始化程序的内容(以及类上的注释)?我无法使用给定的配置重现错误。

此外,查看您的配置,提出一些建议:

    Tomcat 7 不支持 servlet-api 3.1 和 servlet-jsp 2.3。尝试使用 tomcat 8 可能会给您带来一些好运。 如果您决定继续使用 tomcat 7,请确保在您的 pom 中使用上述 jar 的适当 API 版本,并将 servlet-api jar 标记为已提供,因为它将由您的 servlet 容器提供 (Specs for Tomcat versions)。 确保您没有在会话固定配置中使用 changeSessionId(如果有);它是在servelt-api 3.1 中引入的。

如果有问题(以防万一),您还需要查看 /etc/tomcat7/Catalina/localhost/ROOT.xml。 Eclipse 为服务器运行时使用自己的配置元数据,并且仅在定义新服务器时复制服务器的配置。

更新:

另外,请使用@Order(1) 注释您的安全初始化程序,从那里删除@Configuration,因为它由@EnableWebSecurity 提供,然后尝试。还有一件事,替换过滤器注册行并将过滤器直接添加为container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy()).addMappingForUrlPatterns(null, true, "/*"); 并从您的AppConfig 中删除@Import 行。

【讨论】:

您好,我添加了配置类 嗨,无法测试您的配置在 Eclipse 中的工作方式,但您尝试注册 springSecurityFilterChain 两次(在 AppInitializer 中通过注册过滤器和 SecurityInitializer 中)。请删除 SpringSecurityInitializer 类,这对您来说应该可以正常工作。如果没有,请发表评论,并将测试您的配置:) 嗨,抱歉这个类被删除了我发布了所有代码,因为我试图结合几乎所有的东西来解决这个问题:(现在 springSecurityFilterChain 应该只在 AppInitializer 中初始化但是,我得到了同样的错误在 Linux 服务器上运行的 tomcat 上:/ 您好,很抱歉,由于时间紧迫,回复迟了。所以,我尝试了你的配置,不管我把它搞砸了;它可以在 Eclipse 内外以及 tomcat 7 和 8 上运行。建议您在不同的 tomcat 实例上测试您的配置,可能在不同的机器上。毕竟,Java 是独立于平台的!不过有一件事,您能否测试您的 Linux Tomcat 实例是否可以连接到您在 SecurityConfig 中指定的数据源?这可能是这里唯一导致 securityChain 的(静默(日志?))BeanCreationException 以及 null 过滤器的损坏部分。 是的,我在不同的机器上测试过它(也有不同的 tomcat 实例)。数据源没问题,因为休眠使用相同的数据源,当我注释掉springSecurityFilterChain时,我可以启动应用程序并从数据库中获取数据(没有安全性)

以上是关于无法在 Linux 服务器上运行的 tomcat 上启动战争应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Linux Tomcat 错误

从主机 Windows 上无法远程访问 Linux 的 Tomcat 服务器解决方法

Linux Tomcat8无法解压war包

Linux Tomcat8无法解压war包

无法在 VS 代码上运行 Tomcat 服务器

虚拟机上的Tomcat无法访问