My background, which informs my personal taste here:
- Most recent 8 years, have used dynamic languages on the server (Node.js, Ruby, PHP, some Python)
- Have dabbled in C# (ASP.NET MVC and WPF)
- First 4 years professional experience as a Java web developer (servlets, Struts, Spring, Hibernate, etc)
- Have needed recently to generate greenfield Java apps for relatively straightforward CRUD web apps / JSON APIs
I personally would have a hard time going back to Spring or JEE. I initially looked at Play, which is very cool in many respects, but comes with a high complexity/magic level that makes me nervous. Probably it's great, my old bones just can't deal with another long walk to mastery like with Rails.
Here's the stack I have been most comfortable with - note that this has been for relatively simple CRUD app development, and may or may not suit your hyper-enterprise-iot-multitenant-whatever use case:
Kevin likes: Easy to generate single runnable jar, simple route configuration, no heavy abstraction over HTTP (easy to filter, redirect, return status codes, set cookies, etc), support for a variety of modern template engines.
Kevin dislikes: pretty small community around the software
Kevin likes: terse syntax I came to enjoy from Node/Ruby, can easily re-use templates on the front end if needed in Backbone. Integrates easily with Spark.
Kevin likes: <troll>it's web scale</troll>, no schema maintenance, easy to configure for dev/test/prod, easy to create fat models, doesn't require a ton of annotation for persistent fields.
Kevin likes: doesn't matter if I like it, all Java packages live there. Lots to use and choose from both for build tasks and in your code. Make note of the Shade plugin, which makes it easy to generate a single runnable "fat jar":
Kevin dislikes: OMG XML. Super verbose. Pretty slow. Seems to frequently download the Internet. Not fun to extend - consider shelling out to your own scripts:
With the above tools, I found that it's easy to take advantage of the great software packages that do exist for Java, without making my brain hurt too much.
Why Maven rather than Gradle? Gradle has all the libraries in Maven Central. Gradle also has an extensive set of useful plugins built in [1], and many more available externally [2]. In particular, there's a plugin for making a fat jar [3], and even without a plugin, it's a few lines of code [4]. Or you can also make something more exotic like a capsule [5] or a shell script [6], or my preferred format, a 'distribution zip' file containing loose jars and a shell script [7] - which you can even make executable, because i wanted to troll my boss one day [8]).
And there's no XML, it's pretty concise (Groovy syntax, convention over configuration, sensible defaults), and although its raw speed is no better than Maven's, it is smart enough to only execute tasks which are needed (rather than everything, every time, as Maven does), and can run as a daemon to avoid startup costs [9], so in practice it's far faster than Maven. Still downloads the internet now and then, though.
But extension is an absolute joy - there is simply no comparison to Maven. There's a very satisfying spectrum of ways to define your own tasks, from blocks of code right in the build script, to classes defined in the build script [10], to externally packaged plugins, all of which are easy to do and integrate fully with the existing machinery (task dependencies, handling files, inputs and outputs, and so on).
Then there's the stuff you might not even notice until you get off Maven. Gradle builds are graphs of tasks, not sequences of lifecycle phases, so it's trivial to add more tasks, rearrange, tasks, etc. Concrete example: Maven provides a single test task (surefire); if you want a second (say, for functional tests), you can use a plugin (failsafe); if you want a third (say, for external contract tests), you'll need to write a plugin. In Gradle, you'd just make another instance of the test task. It's a few lines of code.
Sorry if i sound like a fanboy or a shill, but Gradle, while far from perfect, is so much better than Maven in every way that it pains me to see a fellow human being suffering under the latter. Seriously, Maven is obsolete. Just use Gradle. Until something better comes along.
> Maven is obsolete. Just use Gradle. Until something better comes along.
Google released Bazel a few months ago, which runs on Linux, tho not Windows, and fully supports JVM-hosted software. It's better than Gradle, so why not move straight from Maven to Bazel? See http://bazel.io/docs/bazel-user-manual.html
Definitely worth considering! I've never used Bazel, so can't give a very helpful answer. Two things discourage me.
Firstly, it's still in beta - 0.1.0 is out [1], and there's plenty to do before 1.0. [2].
Secondly, according to the article on Bazel currently floating up on HN [3]:
"Blaze was designed to work for Google's unified codebase and Bazel is no different. The implication of a unified source tree is that all dependencies for a given software component exist within the tree. This is just not true in the open source world where the vast majority of software packages have dependencies on other libraries or tools, which is a good thing. But I don't see how Bazel copes with this, if at all."
How would i use Bazel to build a project which uses dependencies from Maven Central, or my company's internal repository? It seems that Bazel can fetch jars from Maven repositories [4], but i don't think it does transitive dependencies.
Also, the extension story looks a bit weird [4]:
"Skylark is a superset of the core build language and its syntax is a subset of Python. The following constructs have been added to the core build language: if statements, for loops, and function definitions. It is designed to be simple, thread-safe and integrated with the BUILD language. It is not a general-purpose language and most Python features are not included."
Whilst i'm no fan of Groovy, it's nice to be able to write plugins in a general-purpose language. For example, in one of the build scripts i linked to in my comment, i have a custom build step which processes templates by running another Java program (which was downloaded as a JAR from Maven), and in other builds i've written plugins which call directly into Java libraries (again, which were downloaded as JARs from Maven). Could i do that with Skylark?
You could be right about Bazel's unsuitability for open source software.
> The following constructs have been added to the core build language: if statements, for loops, and function definitions
The whole point of using a declaratively-configured build product rather than procedural scripts is to simplify the logic and be easily extendable. Maven provided the declarative DSL and removed totally the procedural language so you needed an addon like polyglot-maven to do anything "out of the box". Gradle then added the whole procedural language back in to be used with the DSL, but it's hardly used as most build scripts out there are just standard 30-liners. Perhaps Bazel's way of providing just enough procedural features (sequencing, selection, iteration, subroutines), and no more, with the declarative DSL is the best mix.
- Most recent 8 years, have used dynamic languages on the server (Node.js, Ruby, PHP, some Python)
- Have dabbled in C# (ASP.NET MVC and WPF)
- First 4 years professional experience as a Java web developer (servlets, Struts, Spring, Hibernate, etc)
- Have needed recently to generate greenfield Java apps for relatively straightforward CRUD web apps / JSON APIs
I personally would have a hard time going back to Spring or JEE. I initially looked at Play, which is very cool in many respects, but comes with a high complexity/magic level that makes me nervous. Probably it's great, my old bones just can't deal with another long walk to mastery like with Rails.
Here's the stack I have been most comfortable with - note that this has been for relatively simple CRUD app development, and may or may not suit your hyper-enterprise-iot-multitenant-whatever use case:
Web Framework:
Spark 2 (requires Java 8)
http://sparkjava.com/
Kevin likes: Easy to generate single runnable jar, simple route configuration, no heavy abstraction over HTTP (easy to filter, redirect, return status codes, set cookies, etc), support for a variety of modern template engines.
Kevin dislikes: pretty small community around the software
Template Engine:
jade4j
https://github.com/neuland/jade4j
Kevin likes: terse syntax I came to enjoy from Node/Ruby, can easily re-use templates on the front end if needed in Backbone. Integrates easily with Spark.
Model:
Morphia (MongoDB)
http://mongodb.github.io/morphia/
Kevin likes: <troll>it's web scale</troll>, no schema maintenance, easy to configure for dev/test/prod, easy to create fat models, doesn't require a ton of annotation for persistent fields.
Kevin dislikes: sparse documentation
Dependencies/Build:
Maven (duh)
https://maven.apache.org/
Kevin likes: doesn't matter if I like it, all Java packages live there. Lots to use and choose from both for build tasks and in your code. Make note of the Shade plugin, which makes it easy to generate a single runnable "fat jar":
https://maven.apache.org/plugins/maven-shade-plugin/
Kevin dislikes: OMG XML. Super verbose. Pretty slow. Seems to frequently download the Internet. Not fun to extend - consider shelling out to your own scripts:
http://www.mojohaus.org/exec-maven-plugin/
With the above tools, I found that it's easy to take advantage of the great software packages that do exist for Java, without making my brain hurt too much.
HTH!