87 comments

[ 2.7 ms ] story [ 125 ms ] thread
You beat me by a couple of minutes :)

I'm no Java lover, but for some purposes (some non-technical) it's the only real option. These seem like great ways to cut the bloat and still get stuff done.

I am curious what kind of non-technical uses for Java you are talking about?
s/purposes/political reason/g

Several years ago I faced a problem that was extremely computationally intensive, basically the travelling salesman problem [0]. So I wrote the solution in c, fully documented it with a nice config file for all the knobs and the most beautiful makefile I've ever seen. When I presented the work it was as if I had brought a dead cat into the office. They ended up using it as a reference implementation and rewriting it in java, because "We are an Oracle shop" after all. Unsurprisingly the java version didn't work so great, not because java is a bad language, but because it wasn't well suited for the specific problem - it is much more difficult to write java code that can exercise the processor cache the was c code can.

[0] http://en.wikipedia.org/wiki/Travelling_salesman_problem

It's long been ironic that Java has excellent dependency management in the form of Maven - better than any other tool I've used, for any language - but the typical java project had far fewer dependencies than in ruby or node. Glad to see some smaller libraries emerging (and it's worth noting that even e.g. spring is now released as a collection of smaller modules rather than one giant jar).
I'm dabbling with Java occasionally, and what always stumps me is that dependencies are handled differently in every environment. Learning how to add and use an external library in Android is too painful, and zero of that knowledge transfers to Java desktop applications, and zero of that to JBoss WARs.

At some point I just give up and start copy pasting source files; Java's whole environment is too painful for me to want to spend my free time on it, and too complex to learn it in passing at work. It's a lose-lose situation, and I just end up avoiding Java where I can. (Which imo is a shame, because JBoss e.g. turned out to be surprisingly neat once I wrapped my head around it.)

Well there are a bunch of things that are not really Java and it's best to just avoid them; that's not really Java's fault though. I'm not sure what you're talking about with android versus desktop applications though; in android or a desktop application one adds a library as a maven dependency in exactly the same way. (At least, I do).
> Well there are a bunch of things that are not really Java and it's best to just avoid them

I've only ever heard that of Java and C++, and it seems it's always the stuff I cannot avoid because I need it for work.

Your complaint basically boils down to "I don't know how to do it correctly and don't want to learn it". I have a game I'm working on that uses the same setup for both Android and desktop. JBoss does things a crazy way, but for everything else the same approach can be used.
You're doing a bunch of different things there, but none of this stuff is really a secret. You need to be familiar with java class loading[1] and Maven's dependency scopes[2], which is really it's killer feature.

Beyond that, a container, such as jboss, is free define how its things work. One of my favorite things to come out of the Java ecosystem is OSGi, which does dependency management in a very sane way.

[1] http://docs.oracle.com/javase/8/docs/technotes/tools/finding...

[2] https://maven.apache.org/guides/introduction/introduction-to...

It's undeniable that maven can do much more things that other dependency managers, like setting IDE configurations for instance, but that does not make it better.

Do you think it's better than the likes of npm, bower, or composer? where you just say: give me all these things, with at least these versions, and could you please run these scripts also --all at once, in about 30 lines

Every time I want to use mvn I need to start for google .. which was the archetype parameter that I needed?

or so let's run this not-so-common target, no problem I have 5 minutes for a coffee while it downloads all the requirements .. then 5 minutes later says "missing parameter"

> Do you think it's better than the likes of npm, bower, or composer? where you just say: give me all these things, with at least these versions, and could you please run these scripts also --all at once, in about 30 lines of plain text.

Yes. "Run these scripts" leads to snowflake builds: every project ends up slightly different from every other, no-one can resist putting a little "magic" in their build that then goes on to confuse future developers. Requiring every build step to be encapsulated as a plugin, so that there's one and only one way of putting the scm version in your build, one and only one way of bundling your app into an executable, and so on, makes everything much more maintainable.

> Every time I want to use mvn I need to start for google .. which was the archetype parameter that I needed?

You don't need archetypes if you find them problematic. Just start with a minimal pom: groupId, applicationId and version. That's not so hard is it?

> or so let's run this not-so-common target, no problem I have 5 minutes for a coffee while it downloads all the requirements .. then 5 minutes later says "missing parameter"

Either you share your build steps, which means downloading them sometimes, or you copy/paste them everywhere. I know which I prefer. Maven caches quite aggressively (if anything too aggressively), I'm not sure what more it could do.

Running scripts doesn't imply "snowflake builds" - one can just as easily write duplicate plugins that are a mess, and one can also just as easily write encapsulated scripts that do one job and do it well.

It's all about the quality of the developers.

It's not "just as easy". A maven plugin is necessarily a maven module, a first-class module like any of your libraries; unless you go out of your way to make it not, it has versioning, tagging and the like. Even more importantly, since the plugin itself is built with maven, it naturally has dependencies and unit tests, arranged in the same familiar structure as the rest of your code. Everything guides you towards good development practice; of course you could manage your scripts in the same way, but you'd have to do so by hand, and with the best of intentions I've never seen any team that used scripts have the discipline to manage them properly.

Good developers can make good things with bad tools and bad developers can make bad things with good tools yes, but even so, tooling and defaults are extremely important.

> I've never seen any team that used scripts have the discipline to manage them properly

And I'll throw in my personal experience too, which is the opposite: I've never seen any team that used Maven and had the discipline to manage it properly.

Anecdotes don't really get you too far.

Unfortunately this is pretty much the problem you will get. It doesn't have to be about good or bad developers, even good developers will start to apply their own flavor and smart solutions in the build scripts and you will end up with very different way of doing things.

Anyone remember using Ant with Java? Same thing I would say. Maven is convention over configuration for a reason.

I actually somewhat like the XML configuration of Maven. Smart auto-complete in IntelliJ is fantastic. In many JS tools they use a JSON file for configuration, which means one cannot even add comments in the file. And grunt/gulp is worse than Maven, no way you can do anything without writing a custom script with the help of Google.
> Do you think it's better than the likes of npm...

"Better" is a word I don't like, but NPM failed to learn lessons from some of the aspects of dependency management that Maven nailed, e.g. support for standard HTTP caching proxies, immutable versioning.

NPM ran for many years before they switched off the ability for module publishers to overwrite an already published version number with new code.

If you are using Standard Java EE you have exactly one dependency in your pom file.
That's interesting. I'm the person who don't like external libraries and avoids using them unless they are really make me happy. Yet my last small project has 89 libraries in dependencies (including transitive). Is it small number?
My own experiences with Maven have been kind of nightmarish. It puts so much abstraction in between what you see and the underlying reality of command-line tool invocations that it becomes impossible to debug. It also improperly mixes compiling and downloading dependencies into a single tool - more than once I've checked out a project and started compiling it and immediately hit ^C when I noticed it was downloading software without https.
With maven it's a bit like with sex: the first time is sometimes not that funny, and rather painful. And if you're boy you might have not delivered 100% what was expected.
> It puts so much abstraction in between what you see and the underlying reality of command-line tool invocations that it becomes impossible to debug.

That's not the reality. The reality is plugins which are java code - and if you're developing a java program you ought to be capable of debugging java code.

> It also improperly mixes compiling and downloading dependencies into a single tool

"improper" is like "unprofessional" - it's not a real criticism. Having a single command to build is very valuable.

My own experiences with Maven have been kind of nightmarish. It puts so much abstraction in between what you see and the underlying reality of command-line tool invocations that it becomes impossible to debug. It also improperly mixes compiling and downloading dependencies into a single tool - more than once I've checked out a project and started compiling it and immediately hit ^C when I noticed it was downloading software without https.
> Java micro frameworks are an attempt to address the weaknesses of Java while maintaining its strengths

What about all those scripting language for java?

Jruby, Jython, Rhino, Nashorn....

I've looked at ninja a couple of times, and I've always been turned off by what appears to be a lack of Gradle support and the need for a special compilation tool chain. Whenever possible I like to keep tooling as vanilla and commodity as possible.

EDIT: Oops! See my reply below.

By "special compilation tool chain" do you mean Maven? That's not special, that's standard. On the contrary, I was put off by the build example for Jodd needing Gradle to build, rather than Maven. Gradle and its bundled scripting language are heavyweight, which goes against the whole idea of micro-framework philosophy as described in the article, i.e. "much of the functionality wrapped in those [legacy] libraries is no longer really needed for most projects. Micro frameworks are an attempt to address this."
To be perfectly honest, I was misremembering the information from this page:

http://www.ninjaframework.org/documentation/getting_started/...

As I had previously recalled, Ninja's SuperDevMode involved a bunch of bytecode manipulation or something, but that was obviously incorrect.

Re Maven vs. Gradle, I HATE XML with a burning, undying passion. It's just my personal holy war, and while I quite like Maven, I moved to Gradle a while ago to cut out the main source of XML anguish in my life.

Of course, a quick google indicates that that is changing too:

http://www.infoq.com/news/2015/03/maven-polyglot

I do like me some YAML. Realizing that my early-morning phone comment was from half-memories and out-of-date information? Not so much :).

Using Maven for anything but the dependency resolution part feels like coding XML stylesheets. The dependency resolution is awesome, but buildscripts needs to be expressive, do a lot of dirty work and still run fast. Maven does none of that.
Uh, what about Dropwizard[1]? By Github stars, it's 50% bigger than Spark, the most popular in this writeup.

It's really quite good. Provides integrated, configured libraries for REST, JSON, health checks and metrics. Even supports shaded fat jars (which provide a true single "java binary" you can execute with java -jar). It's really quite nice.

[1] https://github.com/dropwizard/dropwizard

(comment deleted)
The author did mention Dropwizard:

The first wave was around lightweight Java frameworks (a few of which we wrote about: Dropwizard vs. Springboot). These delivered lightweight, modern frameworks for Java and helped cut down development time. Now there’s a second wave that’s been recently hitting the scene. That wave is Java micro frameworks.

Ah. Somehow I missed that. Thanks.
In the place I work we can deploy an enterprise Spring web application in 15 seconds, in my local machine. I truly miss those microframeworks, where a deploy is nothing but a restart of the process. I know Spring does so much under the hood, but those benefits do not make up for those ridicilous startup times and deploy scenarios.
Deploy Java enterprise thing in 15 seconds only! What are you running locally, HAL 9000?
15 seconds is not too bad. And still, you can just hot-swap code while it's running.
It used to be about 3-4 minutes with jboss 4. These days all the frameworks I use start up in less than 2 seconds. 15 seconds still seems slow. Take a look at gwizard. It is blazing fast and even faster for running tests since you don't need to start the http container.
Ha-ha. I worked on a project where old WebSphere Portal took 30-60 minutes to start. And shutdown? Noone knows, admins just -KILL-ed it when they wanted to shutdown. You better write your code without bugs. Crazy stuff. 15 seconds? Enjoy that.

Oh, and logs. Nobody knew what happens there. Some alien life chatting about something. May be A.I. was about to born there. Don't think about logs. Use your own files.

And that thing actually worked and was useful to some people.

Well, you must first commit yourself to Micro-Services before you can consider Micro-Frameworks. The Micro-Services hype currently seems disappear as fast as it appeared.
No, this has nothing to with micro-services. The point here is that in Java, most frameworks are huge systems violating the "single responsibility principle", and instead do everything. Currently, it's a movement to split these things into smaller, reusable parts.

Heck, even Spring is looking good now. Many smaller projects, not a huge jar.

Very sparse on details, unfortunately. What makes those frameworks so micro?
I've toyed with both Ninja and Spark a bit in the past and have nothing but positive things to say about them. I mainly use Spark these days when I want a quick web app server to experiment with the JS framework of the day. Spark is great if you want complete control over your stack. So for example I paired it with Dagger for DI and plain JDBC for persistence. But of course it took some amount of effort to create this initial plumbing whereas with something like Ninja (and most other web frameworks), all this is already done for you.
Where is the advantage over using JAX-RS, CDI and JPA? All of these technologies are available per default in any certified application server. Since EE 6 using them is as simple as adding a minimal amount of annotations to your POJOs. For most use cases all of this works out of the box and with next to none additional XML configuration files.
It's been some time since I used JAX-RS, but with the reference impl, Jersey, it was always a hack to use a different DI library like Guice or Dagger and honestly that was the only problem I really had with JAX-RS. So if you mean in comparison to Spark, then one advantage is with Spark you can use whatever DI solution you want.
For folks working with Guice that want a really simple and stripped down framework, check out GWizard:

http://www.gwizard.org

It's basically DropWizard reimagined with dependency injection. Thanks to Guice, there's surprisingly little code involved.

(I'm the primary developer)

The fascinating thing for me about gwizard is that you no longer think about testing from the http layer. You use guice to create a resource and then directly test the resources api. No need to build up urls or post data to a server. No need to spin up a http server at all. Now you get statically typed tests that execute much faster. Win.
I ignore it with ease :)
Hey, don't down-vote this comment, down-vote the title, containing this direct and barefaced lie! (For the record, I am a java programmer with years if daily java coding.)
Your comments are probably being downvoted because they break the HN guidelines (they're not substantive, plus we ask people not to post comments about being downvoted). Nevertheless you are right about the title. I'm not sure how we missed the objectionable baity part, but it's gone now.
The author starts out by saying that one consequence of Java

   being a safe, rigorously tested, backwards compatible 
   language is making some sacrifices around agility and 
   streamlining.
Yet there is nothing in Java as a language that prevents agility and streamlining. It's not a consequence of Java the language it is purely a consequence of Java's community.

It's true that there are a lot of people who when doing java are starting to change the community from the inside and this is good. But pretending like you are fighting the language when doing this is counterproductive.

The language itself is verbose. Instead of overloading operators, for instance, the convention is to have longer method names.
But that's the point: convention is a product of the community. You don't need operator overloading to design classes with shorter method names.
(comment deleted)
operator overloading means changing what + or * do.

Ie, overloading the * operator for a Matrix class so you could do this:

Matrix a = new Matrix();

Matrix b = new Matrix();

Matrix c = a * b;

That is different than function overloading, which you are referencing.

In many cases, the community starts with something that looks like a languages standard library. And Java's is very verbose, so it makes sense that the community would have verbose method names as well.

However, while I can see it taking some getting used to if one comes from a different background, I personally find Java to be nicely self-documenting when using the conventions on display in the standard libraries. Lines are long and sometimes a statement spans multiple, but in many Java libs/apps things do exactly what they're named.

That's convention, the language doesn't prohibit you from overloading. Also, Java is not significantly more verbose than C#.
Read again, operator overloading, not function overloading.
My experience has been that in practice, Java is much more verbose than C#, mainly due to C#'s compact getters and setters, LINQ, and operator overloading.
https://projectlombok.org/ eliminates getters & setters; LINQ and operator overloading I happily live without. The main disadvantage to Java is checked exceptions, but it's possible to avoid them for the most part. Having rewritten some C# code in Java recently, the result was not significantly more or less verbose.

That said, badly written code will suck in either language.

Of all the verbose aspects of Java that you could complain about (getters/setters, checked exceptions, no automatic casting or type inference...) you had to pick operator overloading?!?

Coming from a C++ background, I consider Java's policy on operator overloading to be positively enlightened. There's plenty to complain about in the language, but this isn't one of them. I don't want to program in an ascii-art language.

thanks for this. I always have to hold myself back when one of the worst language features is being seen as something positive. Now I feel I don't have to rant.
It's always a tradeoff. The language is verbose in some places due to legacy commitments. In other places (i.e. compared to dynamically/gradually typed languages), it's to make sure the compiler does work for you. In others (like in the case of operator overloads), there are predictability benefits to only allowing predefined effects from core language features, and building everything on top of those, rather than meta-programming with them.
That is part of why I am currently trying out Kotlin. It is essentially Java with the pain points taken out: non-nullable references, simpler advanced generics, lambdas, classes are final by default as are methods, interfaces can have default implementations of methods, semicolons are optional, fields are removed in favour of properties, etc.

If you want to play with it it is pretty simple to install it in the community (free) version of Intellij and marginally more difficult use without an IDE (you can get the compiler for the command line if you want). It is interoperable with Java so i recommend you try porting one of your existing classes (IntelliJ is supposed to be able to do that for you, but I haven't tried that so far).

Seconded. +1 on Kotlin. I am a really big fan.
Is it too grumpy for me to complain about Spark's name? It postdates the more well-known one by like a year or two.
I'm glad I wasn't the only one confused by that. I'd never heard of Spark the micro-framework and thought the author had somehow Spark the cluster framework into this article.
Especially since Apache Spark is the most committed to Apache project and one of the most popular open source projects in the world.
meh, in most businesses you'll still have to maintain these huge struts/spring apps. You can't call yourself a java web dev and not know all the Spring ecosystem, so if the goal is to make things easier, well for whom? not for new comers who'll still have to learn a bunch of legacy XML backed frameworks and all the JEE stack.
It's funny that the author is selling the concept of microframeworks as a "new trend." It seems that devs are moving away from monolithic frameworks in general (no matter the language) for practical reasons, not because it's a "trend."
(comment deleted)
Why are you getting down voted? I don't see anything particularly wrong with what you said.
I have no idea. Happens to me all the time on HN. :/

I still <3 you guys.

Can someone reframe the definition of the term "micro framework"? I understand the article as micro=very small, but the first example has a lot of batteries included. Isn't that the opposite?
Micro = small in terms of functionality, it should do 1 single thing, for instance 1 micro service just to manage your sharing feature. However, it should be independent and contain also its storage/db, so it won't be that micro in terms of size/code. I'd recommend to look for Netflix talks on the topic, very well done and informative.
Are you talking about micro services? That is (i.e. should be) a very different thing than micro frameworks.
ops, sorry about that - I read too quickly
I don't know if this will help since I suspect you know way more than you're letting on, but I usually find myself framing the definition of a "micro framework" in terms of those I'm most familiar, chiefly Flask. It should have enough "batteries included" to be immediately useful, but small enough that you can keep most/all of the framework's API in your head at any given time.

Then again, I sometimes wonder myself if the definition blurs over the age and maturity of the project. If you look at Flask's ecosystem, there are extensions for nearly everything, making it so that ecosystem as a whole does just as much as a full-featured framework, but you have greater choice as to what components to include (and there's not One True Way to do anything in particular--there's just extensions that are more well-supported than others, well-maintained, and more popular).

I suppose this means that the better analogue is that micro frameworks give you greater control over lower level aspects and make fewer decisions for you (e.g. Django more or less expects you to do things Django's way; Flask has fewer such expectations). Given some of the micro frameworks I've seen, though, I think it's a definite spectrum, not an absolute, and probably depends just as much on the ecosystem and culture surrounding the language as it does on the intent of the creators. Silex (the PHP framework) does very few things, for instance, but it seems that you ought to include healthy chunks of Symfony if you really want it to be usable.

That said, I did stumble across something called "sinetja" [1] which I'd bill as an absolute micro-framework in Java in that it provides a fairly bare bones RESTful router/API and not much else. Think of it as another data point on the spectrum of micro-frameworks but much closer toward the bring-your-own-everything-else half.

So, if you want to roll your own bits to interface with 3rd party libraries or handle common tasks, use a micro-framework. If you want these decisions made for you, don't!

[1] https://github.com/sinetja/sinetja

I can agree with that. A framework that does little on its own with a lot of things to plug in. That would make sense. But the explanation in the article got a little confusing with the first tool doing nearly everything and leaving a big footprint.
This is an odd and uninformative write-up that compares two things (Jodd, Ninja) that aren't really micro-frameworks (say, in the mold of Flask or Sinatra) with one that is (Spark). The comparison seems based purely on advertised features and, even stranger, number of github stars and forks.

Spark is a Sinatra-inspired micro-framework built on the familiar 'call me when this HTTP verb happens' pattern. It does little beyond that but is quick and easy to get up and running.

Despite the forks and stars, it's also probably the least mature of the three - it's not hard to run into a bug or a wart. Those are usually easy to find and fix since it's pretty small. On the other hand, the maintainer has been busy with other things for quite some time and it takes a very long time for PRs to get much attention. The testing setup is an ugly mess so adding a test for your fix is also unpleasant.

A couple of other constraints are that it requires Java 8 and, while it theoretically supports running in an arbitrary servlet container, it's really happiest living in embedded Jetty.

From Spark's homepage copy:

    Why use Spark?

    If you're a Java developer with neither the urge nor time to learn
    a new programming language, and you're not planning to build a
    super large web application that scales in all directions, 
    then Spark might be a great web framework for you.
Maybe they're just being honest, but "use Spark if you're stuck with Java and can't be bothered to learn something else" is a bit off-putting.

I think a better angle looks something like "use Spark if you want a simple, minimal Java microframework" and "if you're coming from Sinatra/Flask/Express and you want something more statically-typed".

On the contrary, that they are willing to admit this fact indicates that they know what they are doing.
I guess it's for people who are stuck with Java because of a corporate choice that has been made to use only this language.

That's very common, and it's usually easier to get approval for a new framework than a different language.

now if I could only get approval for Java 8... now that 7 is officially end-of-lifed...
yea or if you need performance.
Interesting - but people should note there's also something to be said about the more light-weight components of Java EE 6.

For instance CDI for injection and inversion of control, plain JDBC, JAX-RS for RESTful API's on Tomcat or Wildfly app server. Not always necessary to use the more heavy weight technologies such as EJB, JMS, JPA (particularly the last one should be avoided, in my opinion).

Admittedly the concept of an app server can seem antiquated to some, but it's not necessarily a negative thing either.

They do bring useful things to the table, and can be used to build powerful and scalable apps - microservices as well even if they run within a container.