Automate war file creation with Grunt and Maven

The servers I am currently working on use Tomcat and accept war files for deploying my front-end Angularjs apps. I am building an Angularjs app using Yeoman, which doesn't build war files. To get around this I installed Grunt-Shell and modified my Gruntfile.js so it called Maven at the end of the build and created a war file out of the dist folder.

The biggest challenge was modifying the default Yeoman installation so that the Gruntfile.js put the distribution files in a folder structure that Maven accepted. Then adding a pom.xml file and calling Maven created the war file I needed.

    How to call Maven from Grunt

  • Install Maven2. In Ubuntu you can apt-get install maven2
  • Install Grunt-Shell in your project npm install --save-dev grunt-shell
  • Add the WEB-INF and META-INF folders and files to your project, so they are included in the distribution.
  • In your projects Gruntfile.js change the configuration paths to match the Maven defaults
      // configurable paths
      var yeomanConfig = {
        app: 'app',                            //source files
        dist: 'dist/src/main/webapp',  //deploy location
        maven: 'dist'                        //pom.xml will go here
      };
    This creates a distribution folder structure that satisfies the Maven defaults.
    appHome
      |-app
      |-dist
        |-src
        |  |-main
        |    |-webapp
        |      |-META-INF
        |      |  |-context.xml
        |      |-WEB-INF
        |      |  |-web.xml
        |      |-(...distribution files)
        |-pom.xml
  • Add the pom.xml to the copy section
    copy: {
    ...
          maven: {
            files: [{
              expand: true,
              dot: true,
              cwd: '<%= yeoman.app %>',
              dest: '<%= yeoman.maven %>',
              src: [
                'pom.xml',
              ]
            }]
          },
    ...
  • Create the maven shell script
        shell: { 
          maven: {                               // build war file
                options: {                       // Options
                    stdout: true,
                    execOptions: {
                        cwd: 'dist'
                    }
                },
                command: 'mvn clean install'
          }
        }
  • Before the grunt.registerTask section register grunt-shell by adding grunt.loadNpmTasks('grunt-shell');
  • Finally, call the maven task by adding
      grunt.registerTask('build', [
    ...
        'copy:maven',
        'shell:maven'
      ]);
  • UPDATE: 12/11/2013 there is a node package, grunt-war, that will do this https://npmjs.org/package/grunt-war

Read More