springmaventomcatmaven-tomcat-plugintomcat-manager

why deploy tomcat7-maven-plugin with /manager/text messed up the context


If I change the path to anything different from "/" I get 404 error. I mean, if use

<plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><path>/any_word</path><url>http://localhost:8080/manager/text</url>

in the below pom.xml then I will get

http://localhost:8080/authenticate 404 (Not Found)

It seems to me that there is certain issue with context path but I don't know how to fix it. I managed to make the application run in my local Tomcat but certainly I can't apply same approach in production. I deleted the "/" default found in Tomcat. Then, I took away "any_word" and just left "/" in pom.xml. It makes the application run perfectly but, as you can imagine, I can't deploy the application to the root path "/" in production because the server administrator will require obviously from me a specific and unique context path.

I added below all steps and sources relevants to my question. I ordered from the less important to more important from my personal perspective (I do believe it may be something wrong with pom.xml but I may be wrong and I must change some spring configuration or Tomcat Server property).

Take a note that, in browser I do see localhost:8080/calories-tracker no matter if I start/deploy "mvn clean install tomcat7:run-war" instead of "mvn tomcat7:deploy" in a previous started Tomcat server.

1 - In TomcatManager (http://localhost:8080/manager/html/list)

I undeployed “/”

2 - Command Prompt of Windows

C:> mvn tomcat7:deploy

3 - Profile("development")

@Configuration

@Profile("development")

@EnableTransactionManagement

public class DevelopmentConfiguration {



    @Bean(name = "datasource")

    public DriverManagerDataSource dataSource() {



    @Bean(name = "entityManagerFactory")

    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DriverManagerDataSource dataSource) {

4 - catalina.properties

spring.profiles.active=development

5 - settings.xml

  <servers>

       <server>

              <id>tomcat8</id>

              <username>admin</username>

              <password>admin</password>

       </server>

  </servers>

6 - WebAppInitializer

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override

    protected Class<?>[] getRootConfigClasses() {

        return new Class<?>[]{RootContextConfig.class, DevelopmentConfiguration.class, TestConfiguration.class,

                AppSecurityConfig.class};

    }



    @Override

    protected Class<?>[] getServletConfigClasses() {

        return new Class<?>[] {ServletContextConfig.class};

    }



    @Override

    protected String[] getServletMappings() {

        return new String[]{"/"};

    }

}

7 - Web.xml

<web-app>

    <display-name>Archetype Created Web Application</display-name>

    <welcome-file-list>

        <welcome-file>/resources/calories-tracker.html</welcome-file>

    </welcome-file-list>

</web-app>

8- Pom.xml

<build>

       <finalName>calories-tracker</finalName>

       <plugins>

              <plugin>

                     <groupId>org.apache.maven.plugins</groupId>

                     <artifactId>maven-compiler-plugin</artifactId>

                     <version>2.3.2</version>

                     <configuration>

                           <source>${java-version}</source>

                           <target>${java-version}</target>

                     </configuration>

              </plugin>





              <plugin>

                     <groupId>org.apache.maven.plugins</groupId>

                     <artifactId>maven-war-plugin</artifactId>

                     <version>2.6</version>

                     <configuration>

                           <failOnMissingWebXml>false</failOnMissingWebXml>

                     </configuration>

              </plugin>

              <plugin>

                     <groupId>org.apache.tomcat.maven</groupId>

                     <artifactId>tomcat7-maven-plugin</artifactId>

                     <version>2.2</version>

                     <configuration>

                           <path>/</path>

                           <url>http://localhost:8080/manager/text</url>

                           <server>tomcat8</server>

                           <keystoreFile>${basedir}/other/keystore.jks</keystoreFile>

                           <keystorePass>secret</keystorePass>

                     </configuration>

              </plugin>

       </plugins>

</build>

***Added few minutes after created the question The original project can be downlowed from https://github.com/jhades/spring-mvc-angularjs-sample-app. I just made the changes wrote above with Tomcat and Pom.


Solution

  • you need to add $location to your controllers.

    angular.module('common', ['ngMessages'])
        .controller('BaseFormCtrl', ['$scope', '$http', '$location', function ($scope, $http, $location) {
    
            var fieldWithFocus;
    
            $scope.path = $location.absUrl().split('/')[3];
    
            $scope.vm = {
                submitted: false,
                errorMessages: []
            };
    

    then you store the context path in a scope variable and you can use it at the specified controller context. maybe it's not the neatest way, but it works!

    edit: first you need to change in login page the following tag for require

    <script type="text/javascript" data-main="./js/run-loggin-app"
            src="../bower_components/requirejs/require.js"></script>
    

    then, if you like to see it in action

    <link rel="stylesheet" type="text/css" href="/{{path}}/resources/bower_components/pure/pure.css">
    <link rel="stylesheet" type="text/css" href="/{{path}}/resources/bower_components/pure/grids-responsive.css">
    <link rel="stylesheet" type="text/css" href="/{{path}}/resources/public/css/pure-theme.css">
    <link rel="stylesheet" type="text/css" href="/{{path}}/resources//public/css/calories-tracker.css">
    

    but this will take some milliseconds to load which means that you will see for an instance the page without any css, till angular loads.

    you can see the difference you change the links to be of relative path.

    <link rel="stylesheet" type="text/css" href="../bower_components/pure/pure.css">
    <link rel="stylesheet" type="text/css" href="../bower_components/pure/grids-responsive.css">
    <link rel="stylesheet" type="text/css" href="../public/css/pure-theme.css">
    <link rel="stylesheet" type="text/css" href="../public/css/calories-tracker.css">
    

    you can start by changing the links first and the POST/GET endpoints and then decide what to do with the styling links.