Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running war file from a Maven Tomcat Plugin -- is plugin using the wrong file?

I am developing a web app using Vaadin and configuring it so it will run in a development, staging, and production setting. My problem is that I am having trouble getting the Tomcat7 Maven plugin to run my war file. The war file is fine -- I've examined it with an editor. I am using placeholders in my spring-context.xml (which I call applicationContext.xml) to stand in for the database info. I use Maven resource filtering to replace to place holders with real data. This works in the war file.

However, when I trying run with a Tomcat7 Maven plugin, I get the following error (I left out the cleaning and testing messages):

[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}]

Here's my interpretation of what is going on. Please tell me if I'm wrong.

Vaadin uses GWT, so that gets compiled. Then the war file get assembled and installed. The resources are copied and filtered. Maven checks if it need to compile, but it doesn't. Then Tomcat starts up and begins to configure itself. When it gets to the dataSource in applicationContext.xml it chokes because it finds placeholders instead of real data. But why? Resources has already run, and the war file and war directory have the correct data.

Here are parts of my POM. I've changed it a lot but this is what I've landed on:

<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>
like image 328
ksnortum Avatar asked Aug 27 '12 22:08

ksnortum


1 Answers

It turns out this is a bug in tomcat7-maven-plugin, or at least it isn't working as I would expect. It does NOT use the configuration files in the war file or directory when it runs the Tomcat server from Maven. You can see this in a Github project I did:

Click here

EDIT: Okay, it's not a bug per se, but the Tomcat plugin and the resource filtering plugin doesn't talk to each other. No reason they should, except that if you filter resources, the Tomcat plugin will never find them.

You have to specifically tell the Tomcat plugin where the filtered resources are. The default is ${project.build.directory}/${project.build.finalName} so you can add this to your Tomcat plugin configuration:

<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>
        ...
like image 148
ksnortum Avatar answered Oct 19 '22 20:10

ksnortum