

Spring Boot で作成したアプリケーションをGradleでwar作成し、既存のTomcat上にデプロイしようとしています。

warの作成には成功しましたが、webappに配置してTomcatを起動すると以下のようなエラーが出てしまいます。

＜Catalina.out＞

[code]

    重大 [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start: 
    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/app]]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:986)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.IllegalStateException: Duplicate Filter registration for 'springSecurityFilterChain'. Check to ensure the Filter is only configured once.
        at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.registerFilter(AbstractSecurityWebApplicationInitializer.java:217)
        at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.insertSpringSecurityFilterChain(AbstractSecurityWebApplicationInitializer.java:151)
        at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.onStartup(AbstractSecurityWebApplicationInitializer.java:124)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        ... 10 more
    
[/code]

eclipseで実行する場合にはSpringBootに含まれるTomcatを使用しており問題なく動作しています。  
サーバ上のTomcatとバージョンを合わせるためにenbedしているTomcatは除いてバージョンの指定を行っています。  
また、Gradleでwarの作成時にはTomcatのjarは含まないように定義しています。

＜build.gradle＞

[code]

    buildscript {
        ext {
            springBootVersion = '1.5.9.RELEASE'
            tomcatVersion = '8.5.24'
        }
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
    }
    
    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'war'
    apply plugin: 'org.springframework.boot'
    
    version = '0.0.0-SNAPSHOT'
    sourceCompatibility = 1.8
    
    repositories {
        mavenCentral()
    }
    
    [compileJava,compileTestJava]*.options*.encoding='UTF-8'
    
    processResources.destinationDir = compileJava.destinationDir
    compileJava.dependsOn processResources
    
    dependencies {
        compile('org.springframework.boot:spring-boot-starter-web') {
            exclude(module: 'spring-boot-starter-tomcat')
            exclude(group: 'org.apaceh.tomcat.embed')
        }
        compile('org.springframework.boot:spring-boot-starter-thymeleaf')
        compile('org.springframework.boot:spring-boot-starter-security')
        compile('org.springframework.boot:spring-boot-devtools')
        compile('org.springframework.boot:spring-boot-starter-mail')
    
        providedCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
        providedCompile("org.apache.tomcat.embed:tomcat-embed-el:${tomcatVersion}")
        providedCompile("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}")
        providedCompile('org.apache.tomcat.embed:tomcat-embed-logging-juli:8.5.2')
        providedCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
        providedCompile("org.apache.tomcat:tomcat-jdbc:${tomcatVersion}")
        providedCompile("org.apache.tomcat:tomcat-jsp-api:${tomcatVersion}")
    
        compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4')
    
        compile('org.projectlombok:lombok:1.16.16')
    
        compile('org.postgresql:postgresql:9.3-1100-jdbc4')
    
        compile('org.seasar.doma.boot:doma-spring-boot-starter:1.1.0')
    
        testCompile('org.springframework.boot:spring-boot-starter-test')
    }
    
    war {
        archiveName 'app.war';
    }
    
[/code]

TomcatのログにはSpring Security
のフィルターが重複してるとありますが、プロジェクト内で使用しているSpringSecurityのFilterChainに関わる設定はConfigクラス一つだけです。

＜AppWebSecurityConfigurer.java＞

[code]

    ・・省略
    @Configuration
    @EnableWebSecurity
    public class AppWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
        @Autowired
        AppLogoutHandler logoutHandler;
    
        @Autowired
        AppLoginSuccessHandler loginSuccessHandler;
    
        @Autowired
        LoginService loginService;
    
        @Bean
        AppLoginSuccessHandler loginSuccessHandler() {
            return new AppLoginSuccessHandler();
        }
        @Bean
        PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/app/auth/**")
                    .authenticated()
                    .antMatchers("/js/**"
                            ,"/css/**"
                            ,"/images/**"
                            , "/vendor/**"
                            ,"/app/**")
                    .permitAll()
                .and()
                .formLogin()
                    .loginPage(URL_LOGIN)
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .successHandler(loginSuccessHandler)
                    .failureUrl(URL_LOGIN + "?error=true")
                    .permitAll()
                .and()
                .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher(U_LOGOUT))
                    .logoutSuccessUrl(U_HOME_INDEX)
                    .deleteCookies("JSESSIONID")
                    .addLogoutHandler(logoutHandler)
                    .invalidateHttpSession(true)
                    .permitAll()
                .and()
                .sessionManagement()
                    .sessionFixation()
                    .newSession()
                    .invalidSessionUrl(URL_LOGIN);
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(loginService).passwordEncoder(passwordEncoder());
        }
    }
    
[/code]

私の無知ゆえどこに見当をつけて調べていけばいいのかわからず質問させていただきます。  
どなたかお分かりになる方がいらっしゃいましたら、お教え願いますでしょうか。


CC BY-SA 3.0
2018-01-23T10:27:06.393
41153
2018-07-05T07:37:32.720
27116
question
spring-boot tomcat gradle
Spring Boot でGradleを使用してwarを作成し　tomcat上で起動してもエラーが発生する


自己解決ししました。  
SpringSecurityのConfigクラスを指定するために、Initializerで指定していました。

[code]

    public class AppSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
    
        public AppSecurityWebApplicationInitializer() {
            super(AppWebSecurityConfigurer.class);
        }
    
        ///Override method////
    
    }
    
[/code]

しかし、Spring や
SpringMVCを使用している場合は、先に実行しているInitializerで@Configurationを読み込んでいるため、重複して設定されているようでした。

なぜ、組み込みのTomcatでは動くのかまでは調べられていませんがとりあえず解決です。


CC BY-SA 3.0
2018-01-23T11:11:04.000
41154
2018-01-23T11:11:04.000
27116
41153
answer