5

我正在使用 Vaadin 开发一个 Web 应用程序并对其进行配置,以便它可以在开发、登台和生产环境中运行。我的问题是我无法让 Tomcat7 Maven 插件运行我的 war 文件。战争文件很好——我已经用编辑器检查过它。我在我的 spring-context.xml(我称之为 applicationContext.xml)中使用占位符来代替数据库信息。我使用 Maven 资源过滤来用真实数据替换占位符。这适用于战争文件。

但是,当我尝试使用 Tomcat7 Maven 插件运行时,出现以下错误(我遗漏了清理和测试消息):

[INFO] 
[INFO] --- gwt-maven-plugin:2.4.0:compile (default) @ dpt ---
[INFO] auto discovered modules [com.catalystitservices.nike.dpt.widgetset.DptWidgetset]
[INFO] com.catalystitservices.nike.dpt.widgetset.DptWidgetset is up to date. GWT compilation skipped
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ dpt ---
[INFO] Packaging webapp
[INFO] Assembling webapp [dpt] in [C:\Projects\DPT\target\dpt]
[INFO] Processing war project
[INFO] Copying webapp webResources [C:\Projects\DPT\src/main/webapp/] to [C:\Projects\DPT\target\dpt]
[INFO] Copying webapp resources [C:\Projects\DPT\src\main\webapp]
[INFO] Webapp assembled in [1407 msecs]
[INFO] Building war: C:\Projects\DPT\target\dpt.war
[INFO] 
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ dpt ---
[INFO] Installing C:\Projects\DPT\target\dpt.war to C:\Users\ksnortum\.m2\repository\com\nike\dpt\dpt\1.1-SNAPSHOT\dpt-1.1-SNAPSHOT.war
[INFO] Installing C:\Projects\DPT\pom.xml to C:\Users\ksnortum\.m2\repository\com\nike\dpt\dpt\1.1-SNAPSHOT\dpt-1.1-SNAPSHOT.pom
[INFO] 
[INFO] >>> tomcat-maven-plugin:1.1:run (default-cli) @ dpt >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ dpt ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 3 resources
[INFO] Copying 3 resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ dpt ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< tomcat-maven-plugin:1.1:run (default-cli) @ dpt <<<
[INFO] 
[INFO] --- tomcat-maven-plugin:1.1:run (default-cli) @ dpt ---
[INFO] Running war on http://localhost:8080/dpt
[INFO] Creating Tomcat server configuration at C:\Projects\DPT\target\tomcat
Aug 27, 2012 2:51:57 PM org.apache.catalina.startup.Embedded start
INFO: Starting tomcat server
Aug 27, 2012 2:51:57 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.29
Aug 27, 2012 2:51:58 PM org.apache.catalina.core.ApplicationContext log
INFO: Set web app root system property: 'webapp.root' = [C:\Projects\DPT\src\main\webapp\]
Aug 27, 2012 2:51:58 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing log4j from [classpath:log4j.properties]
Aug 27, 2012 2:51:58 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
27.08.2012 14:51:58 INFO  (ContextLoader.java:272) - Root WebApplicationContext: initialization started
27.08.2012 14:51:58 INFO  (AbstractApplicationContext.java:500) - Refreshing Root WebApplicationContext: startup date [Mon Aug 27 14:51:58 PDT 2012]; root of context hierarchy
27.08.2012 14:51:58 INFO  (XmlBeanDefinitionReader.java:315) - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
27.08.2012 14:51:58 INFO  (XmlBeanDefinitionReader.java:315) - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext-security.xml]
27.08.2012 14:51:59 INFO  (SpringSecurityCoreVersion.java:33) - You are running with Spring Security Core 3.1.0.RELEASE
27.08.2012 14:51:59 INFO  (SecurityNamespaceHandler.java:57) - Spring Security 'config' module version is 3.1.0.RELEASE
27.08.2012 14:51:59 INFO  (HttpSecurityBeanDefinitionParser.java:229) - Checking sorted filter chain: [Root bean: class [org.springframework.security.web.context.SecurityContextPersistenceFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 300, Root bean: class [org.springframework.security.web.authentication.logout.LogoutFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 400, <org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0>, order = 800, Root bean: class [org.springframework.security.web.authentication.www.BasicAuthenticationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1200, Root bean: class [org.springframework.security.web.savedrequest.RequestCacheAwareFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1300, Root bean: class [org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1400, Root bean: class [org.springframework.security.web.authentication.AnonymousAuthenticationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1700, Root bean: class [org.springframework.security.web.session.SessionManagementFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1800, Root bean: class [org.springframework.security.web.access.ExceptionTranslationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1900, <org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0>, order = 2000]
27.08.2012 14:51:59 INFO  (PropertiesLoaderSupport.java:177) - Loading properties file from file [C:\Projects\DPT\target\classes\log4j.properties]
27.08.2012 14:51:59 INFO  (DefaultSingletonBeanRegistry.java:433) - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3358fd70: defining beans [org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,cdbController,forecastController,genericGridController,productionPlanController,productionScheduleReportController,actualsDao,cdbDao,dateDimDao,developerDao,factoryCapacityOverrideDao,factoryDao,familyDao,forecastDao,globalTotalOverrideDao,linePlanDao,modelOfferingDao,multiSourceDao,productionCategoryDao,productionPlanDao,regionDao,dptApplication,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.config.internalBeanConfigurerAspect,org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#0,org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,txManager,messageSource,localeResolver,com.catalystitservices.nike.util.VaadinApplicationObjectSupport#0,dataSource,jdbcTemplate,org.springframework.security.filterChains,org.springframework.security.filterChainProxy,org.springframework.security.web.DefaultSecurityFilterChain#0,org.springframework.security.web.DefaultSecurityFilterChain#1,org.springframework.security.web.DefaultSecurityFilterChain#2,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.userDetailsServiceFactory,org.springframework.security.web.DefaultSecurityFilterChain#3,org.springframework.security.provisioning.InMemoryUserDetailsManager#0,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource#0,org.springframework.security.access.vote.AffirmativeBased#1,org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor#0,org.springframework.security.methodSecurityMetadataSourceAdvisor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
Aug 27, 2012 2:51:59 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Could not resolve placeholder 'db.driverClassName' in string value [${db.driverClassName}]

这是我对正在发生的事情的解释。如果我错了,请告诉我。

Vaadin 使用 GWT,因此可以编译。然后war文件被组装和安装。资源被复制和过滤。Maven 检查它是否需要编译,但它不需要。然后 Tomcat 启动并开始自我配置。当它到达 applicationContext.xml 中的数据源时,它会窒息,因为它找到的是占位符而不是真实数据。但为什么?资源已经运行,war 文件和 war 目录有正确的数据。

这是我的 POM 的一部分。我已经改变了很多,但这就是我的目标:

<build>
    <finalName>dpt</finalName>

    <filters>
        <filter>src/main/resources/props/dev.properties</filter>
    </filters>

    <resources>
        <resource>

            <!-- Currently, log4j.properties -->
            <directory>src/main/resources</directory>
            <filtering>true</filtering>

            <includes>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>

    <plugins>

        <!-- WAR file plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>${mavenWarPlugin}</version>

            <configuration>
                <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
                <warName>dpt</warName>

                <filters>
                    <filter>src/main/resources/props/dev.properties</filter>
                </filters>

                <webResources>
                    <resource>

                        <!-- Currently, spring context files -->
                        <directory>src/main/webapp/</directory>
                        <filtering>true</filtering>

                        <includes>
                            <include>**/*.xml</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
4

1 回答 1

13

事实证明这是 tomcat7-maven-plugin 中的一个错误,或者至少它没有像我预期的那样工作。当它从 Maven 运行 Tomcat 服务器时,它不使用 war 文件或目录中的配置文件。你可以在我做的一个 Github 项目中看到这一点:

点击这里

编辑:好的,这本身不是一个错误,但 Tomcat 插件和资源过滤插件不会相互通信。没有理由他们应该这样做,除了如果您过滤资源,Tomcat 插件将永远找不到它们。

您必须明确告诉 Tomcat 插件过滤的资源在哪里。默认值为 ${project.build.directory}/${project.build.finalName},因此您可以将其添加到 Tomcat 插件配置中:

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>${tomcat7MavenPlugin}</version>

        <configuration>
          ...

          <!-- Have Tomcat look in the file filtering folder -->
          <warSourceDirectory>
            ${project.build.directory}/${project.build.finalName}
          </warSourceDirectory>
        </configuration>
        ...
于 2012-08-29T22:16:44.600 回答