97

We are doing a web application with AngularJS and we like the idea of using Bower for Dependency Management and Grunt for building, running tests etc. (Yeoman)

The server is done with Java using Maven, so of course we would like with a simple mvn install build everything (web application + server)

So what approach you took and why?

  1. Treat them as two different applications, which in fact they are. So using different building methods/tools is acceptable.

  2. Forget about Grunt Bower, use Maven plugins to build, run tests, manage dependencies for the web application. If that is the case, which ones?

  3. Use Maven exec plugin to call Grunt to build the front-end webapp. I see this more as a hack than a solution.

  4. Other.

An approach easier to integrate with Jenkins is a plus.

starball
  • 20,030
  • 7
  • 43
  • 238
void
  • 1,484
  • 1
  • 15
  • 18
  • 2
    3 years on, tool integration has obviously improved. This maven plugin seems to have most things covered: https://github.com/eirslett/frontend-maven-plugin – earcam Feb 05 '16 at 13:16

5 Answers5

73

After working with about every asset pipeline tool in the Java toolkit for a while I have come to a few conclusions:

Java Based Tooling

There are a handful of tools out there but the most popular are JAWR and Wro4J. The biggest problem with both of these is that they are mostly Rhino based (WRO4J now has some Node support) and Rhino is dog slow compared to Node based tools. You also have to consider that the JavaScript tooling is rapidly maturing so you should be looking for tools that can move quickly.

  • WRO4J - Support is great, Maven AND Eclipse integration are great the list of plugins is extensive and the framework is flexible enough that with some elbow grease you can write a plugin for whatever you need. If you're confined to a Java based asset pipeline this is for sure the way to go. The issue with Wro4j is that it is slow ( even when it kicks off Node processes ) relative to Node based tools.
    To give some real world numbers compiling and concatenating 25 asset bundles containing LESS, CSS CoffeeScript and JavaScript takes about ~35s when using Rhino and ~15s using Wro4j's Node support on a 2013 iMac with 16G of RAM. Using Grunt+Node takes about 2s on my puny MacBook Air.

  • JAWR - The integrations and feature list are pretty good but the docs aren't great and writing your own plugins can be a little tricky. When I originally wrote this post JAWR was in the middle of a 4 year hiatus but is now back under active development as of Jan 2014. If you choose to investigate Java Tools this is worth investigation.

Node Based Tooling (integrated with Ant/Maven Builds)

  • Grunt - It's easy, has a fantastic plugin ecosystem and the community is massive. If there is something you need to do you can bet there is a plugin for it - possibly even one written by the creators of grunt. The major criticisms of Grunt are that it is configuration driven which makes for a very setup easy but is not the "Node Way." It's also worth mentioning that Grunt tasks are not easily composable so for a complex JavaScript build pipeline Grunt may not be ideal.

  • Gulp - Gulp is the fast growing alternative to Grunt. Its concurrent by default and uses streams to avoid temporary writes to the file system which can considerably speed up your build. Gulp is very idiomatic and has an emphasis on code > configuration and while this gives you a lot of power it's is not ideal for teams that don't have a core competency in JavaScript.

The only potential hang up for JavaScript based tooling is that you will have to have Node, npm and grunt-cli/gulp on any machine that needs to do the compilation. If you don't have access to your CI machines or are not using artifact based deploys this may be a hard sell.

Integrating this into your Maven project is pretty easy and you have quite a few options. You can use the Maven ant-run plugin, you can run an ant exec task and call it from Maven or best of all you can just use the maven exec task.
Below is the code to integrate this into the Maven lifecycle using the exec plugin if this is helpful to anybody.

    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.2.1</version>
      <executions>
        <execution>
          <phase>prepare-package</phase>
          <goals>
            <goal>exec</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <executable>grunt</executable>
      </configuration>
    </plugin>
Dark Star1
  • 6,986
  • 16
  • 73
  • 121
Baer
  • 3,690
  • 25
  • 24
  • 1
    Thanks for the detailed answer. I think I will go for the Node Based Tooling option. New to Grunt I like what I've seen so far, and would be great if I can have the best of two worlds. I didn't know about WRO4J and JAWR existance. Thanks again. – void Apr 12 '13 at 16:14
  • wro4j integrates the less4j processor which is java based implementation of less.js whose performance is comparable to the node.js native one. – Alex Objelean Apr 13 '13 at 20:44
  • 1
    The reason why wro4j isn't that fast with node.js, is mostly because it requires disk IO operations for each execution. This could be improved only if node.js based processes (such as lessc) would allow in-memory compilation of resources. – Alex Objelean Apr 13 '13 at 20:50
  • I've been using grunt on front end projects, but never had a need to package together with a maven project until now. I still treat the front end and back end as two separate projects for development, but bundle them together sometimes with my build process. The exec-maven-plugin was exactly what I needed. Thanks! – gstroup Apr 18 '13 at 19:51
  • 12
    Does this process support failing the `Maven` build if the `grunt` build fails? – Snekse May 20 '13 at 17:06
  • 6
    Any exec task that doesn't return properly should fail the build. http://stackoverflow.com/questions/3480162/can-maven-exec-plugin-fail-the-build – Baer May 20 '13 at 23:09
  • JAWR is active again since 2014. The last update time as of this comment is 05/08/2014. – merlin Jun 16 '14 at 00:59
  • Nice answer. Unfortunately our build is still on Ant (moans...), but of course the solution you outlined works fine there as well. I have some experience with gulp so that's the one I'd likely choose as well. – John Lockwood Oct 07 '16 at 02:45
24

For anyone still looking for more information on this topic, one of the creators of Yeoman has a good article (written a few months after this question was originally asked) that expands on the original answer with a bit more detail:

Jeff Smith
  • 695
  • 6
  • 14
13

Then there's also the frontend-maven-plugin: https://stackoverflow.com/a/19600777/320399 It downloads Node and NPM for you (locally to your project), downloads Grunt via that NPM (run by that Node) and then runs Grunt (via that Node). It's self-bootstrapping, and you don't need Node installed on the machine to build the project. Just one command; mvn install.

Community
  • 1
  • 1
13

You might want to checkout http://jhipster.github.io/ : it's a Yeoman generator, that generates an application which has Maven, Grunt and Bower all working together.

It's a bit like your third option, but everything is configured for you, which isn't that easy. It's also generating the basic AngularJS and Java REST services for you.

Julien Dubois
  • 3,678
  • 1
  • 20
  • 22
  • 1
    It's too late for my project to start with a freshly generated application. But this is great and very helpful, I will lend some of the solutions from the generated application and use in my project. Thanks! – Matsemann Dec 04 '13 at 12:29
  • 2
    Actually, you just need to include the yeoman-maven-plugin and this allows you to put all the JavaScript config stuff (bower, npm, grunt) as siblings to the pom.xml (exactly where these files should belong IMO), and upon mvn install it will build just everything - including your webapp under src/main/webapp. Took me less than half an hour to port an existing project to that structure. Of course you should have a look at the example app at https://github.com/jhipster/jhipster-sample-app – raven_arkadon Apr 21 '14 at 10:39
4

after few hours spent over this problem, i can say this:

maven and grunt do not play well, but it can be enforced..

Here is a plugin description for running Grunt via Maven build

i hope this helps :)

Community
  • 1
  • 1
Nadav Leshem
  • 193
  • 9