This project is nice but it's important to mention that there is actually a "Java micro web framework" standard called JAX-RS that is pretty widely adopted (with solid open-source implementations by JBoss, Apache, Oracle and others). Here's a rather old comparison of JAX-RS implementations: http://www.infoq.com/news/2008/10/jaxrs-comparison
I see the term "get" twice. The class name is redundant with the resource path. I suppose not a huge problem because many MVC frameworks require classes, but not even close to Sinatra.
You're counting required language keywords towards what makes a micro-framework? That's bullshit. You're never going to get away from some of the keywords in Java, nor does that make JAX-RS less 'micro'
You're missing out on all the power that jax-rs gives you though with how it binds to things like jackson.
eg:
@Path("/companies")
public class CompanyResource {
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Company getFromDB(@PathParam("id") String companyId) {
return SomeDatabase.get(companyId);
}
}
public class Company {
List<Person> employees;
}
public class Employee {
String name;
int age;
Employee manager;
}
You start to understand how good jax-rs and modern Java can be when you actually start using it for something useful.
get(new JsonTransformer("/companies/:id") {
@Override
public Company handle(Request request, Response response) {
return SomeDatabase.get(request.params(":id"));
}
});
public class Company {
List<Person> employees;
}
public class Employee {
String name;
int age;
Employee manager;
}
So it's got the same functionality as the industry accepted standard, same concision as the industry accepted standard, only the syntax is different. Why not just use the industry accepted standard syntax, then? Why isn't Spark a JAX-RS implementation?
I haven't written Java in a while and I've never seen any other examples of JAX-RS, so feel free to take this with a grain of salt. That said, in my opinion JAX-RS looks uglier, less clear, and more verbose than Spark, and I'd want an alternative to JAX-RS were I ever to write Java web code.
I have done JAX-RS, for small web apps where you aren't trying to build in the kitchen sink, Spark is looking nice. Spark doesn't seem to be trying to replace JAX-RS, it seems to just be making the syntax a bit easier and doing lightweight REST in a way I find unique and really applicable to small web apps. He uses plain Java main.
You can use a plain Java main with JAX-RS, too (when using an embedded server like, say, Jetty – just like Spark). Dropwizard does exactly that.
Well, I don't know... I'm sure Spark is great, but dropping a widely accepted, well established and quite liked standard just for an arguably "bit easier" syntax (especially when there haven't been any major complaints about the standard syntax) seems like the wrong tradeoff. I would have loved a JAX-RS implementation with other compelling features like performance, monitoring etc. Another good JAX-RS implementation is always welcome.
You can step through all of Spring in your debugger with no problems, whether you configure it in xml or via annotations. Spring is not "programming in xml".
Also, Python has decorators and Python 3 will soon have function annotations.
All the nesting and redundancy come from Java itself. Verbose as it may be, after you use any language for a while you will see right through the syntax and it will not add (much) cognitive load to your work.
I think the value here is in having a micro framework that allows you to put together a web app without having to juggle a horribly complex abstraction hierarchy for even the simplest of tasks.
You don't call a framework "micro" based on the amount of code it takes to achieve certain tasks. You call it "micro" because it's small enough that you can learn and truly master in a short time (and you get that by cutting out as many non-essential features as possible).
The downside when using a micro framework is that you always walk a fine line between simplicity and code reuse. Because of this, as the application grows you do end up writing more code than with a complex framework because you slowly start reinventing the wheel -- this is the old argument you hear over and over (Flask vs Django, Sinatra vs Rails, BackboneJS vs AngularJS, etc.)
Same symptom is shown in Haskell circles. I suspect it might be due to the enthusiasts of these languages often being mathematicians. And mathematicians love crazy sigils, as we know.
usually scala libraries come with an easy to read/write DSL version of the API along with a more verbose java-style API shown above. Many libraries don't document with a plenty of examples. But, it really takes 10 minutes to learn DSL version in many cases. And, it gives you wings. There are plenty of benefits of DSL. You can research online about them.
Scalatra had some good features, but the installation instructions required an entirely new build or package system, giter8, which in turn requires another package, conscript. Two packages to install another package? This is just an unnecessary barrier to entry.
yah, it required me to install a JVM. And JVM required me to purchase a personal computer that can host the JVM. And electricity and stuff. Such an unnecessary barrier to entry.
I made a prototype of this (including extracting arguments Sinatra-style, which I think is its coolest bit), and didn't encounter any serious problems with this approach.
I've reviewed Lambdas and still don't think the syntax is clearer to me than just using an Anonymous Class. Either way, less configuration and less annotations, whatever lets me do that I could buy into as long as the debugging isn't a mess.
Definitely something that was needed, microframeworks are great. Restlet I used long ago but still very Java enterprisey. Play! is like Java's Django/Rails and now Spark is the Sinatra, simple and minimal. Scalatra mentioned here looks great as well, all these wonderful minimal Java toys.
This is fantastic. I know a lot of programming languages and I love them all for different reasons, but I think I am most productive and most likely to produce error-free programs in Java. All the verbosity that people hate is a feature to me, I know exactly what my program is doing.
However, I have done 95% of my web development in Ruby due to the Sinatra and Rails frameworks. The developer experience is too good to ignore. I'm hoping this can replace my Sinatra use case ... I don't think the magic of Rails could ever be replicated in Java.
Annotations are great until you want to do ANYTHING dynamic. "It's a trap!" Everytime without fail I want to do this kind of thing I end up ripping it all out later when I need more flexibility.
If Dropwizard lets me fall back to non-annotations, then awesome.
Really, five minutes ago I didn't know either of these projects existed, so right now I'm feeling a little giddy either way you slice it!
I don't know what you mean by dynamic but dropwizard is just a selection of other libraries wired together into a framework with supporting code (config, etc) which is built for high performance HTTP services serving JSON, but it can do HTML rendering. The above code is compliant with any JAX-RS implementation, JAX-RS is probably the most well done Java spec I've ever worked with which isn't saying much, but it doesn't suck.
I think by dynamic, they mean that you can't really edit the annotation at runtime. In this case, it would be that you can't choose the HTTP verb using an if statement, for example. Other annotations have parameters, which you might also want to tweak.
Annotations trade flexibility for succinctness and readability. That's often a great reasonable tradeoff and a good place to start, but you might find yourself ripping them out later.
One example would be that with Spark you could procedurally create and register multiple Route instances. That is not an option with an annotation-based API that requires you to have a distinct annotated class per route.
More abstractly, one of the characteristics of object-oriented design is the use of polymorphic objects. APIs which require you to define monomorphic annotated classes violate this and lose generality as a result. They are effectively class-oriented or method-oriented rather than true OO.
Why would you want that feature? Also I'm pretty sure nothing about jaxrs annotations prevents such a thing from being possible but the servlet container may get in your way of doing it easily.
Why would you want to procedurally generate routes or verbs? I dunno, perhaps there might be a use case where one would want to define them in configuration or a database. But being able to do something like this is not a "feature," it's just the inherent flexibility of expressing semantics in code.
Why would you want an API that breaks the flexibility of code by forcing it to be glorified XML?
By dynamic I think he just means that annotations are a really hacky way to do things. You use annotations in place of java code, and while you can tweak java code you can't tweak what an annotation does or how it does it.
> By dynamic I think he just means that annotations are a really hacky way to do things.
Why?
> You use annotations in place of java code, and while you can tweak java code you can't tweak what an annotation does or how it does it.
Why can't you tweak an annotation? Annotations are built into the language, the entire point of them is to allow code to detect their presence in the bytecode and thus react at runtime. e.g. wrap a method marked as @Transactional in a database transaction.
This is sort of getting off topic, but... I agree that annotations are magical. The good news is that they announce magic is happening. When I see unfamiliar annotations in Java code I know to look at their javadocs. I like that kind of magic much more than magic by convention (e.g. the location of the given file on disk).
Dropwizard is very well implemented and uses annotations for achieving a very concise syntax as far as Java goes. No XML too, which is a big plus for me.
But when I though how many lines some webapp I was writing would take in Clojure, I went to the corner of the room and cried.
My conclusion for now is that "first versions" should be written in dynamic languages.
Right. This project should be compared to Jersey (the JAX-RS implementation Dropwizard uses). Dropwizard has other components as well (for monitoring, DB etc.).
This looks really cool, I can't wait to hack around with this!
Question for the community: I don't have enough experience to know how this stacks up against other servers out there. Also, how do the people HN enjoy using java as a webserver (lang-wise, scaling-wise, etc)?
I enjoy using it, except when we are forced to target Websphere.
JBoss, Jetty and Tomcat are pretty good in terms of taking care of load in heavy sites.
Most JVMs (Oracle, IBM, Azul, Aonix, ...) are able to achieve very good performance levels.
There is the tooling one gets, not only in terms of IDE support, but also for monitoring the state of the server processes and how load is being affected.
Finally if Java the language, doesn't appeal you, there are plenty of languages that target the JVM as well.
I would use Java for GWT, if nothing else. Being able to write a huge and complex application for the web, using Java both for the client and server code is something I would not want to live without (links in my profile for examples).
But besides that, Java is extremely mature, has great tooling, huge community and of course an enormous ecosystem with all the third party tools and libraries that come with it. The language is a bit primitive (but improving with each release), and the 'enterprise consultant' mindset of complexity for its own sake can be a turn-off, but overall, yeah, I like using Java.
Also, how do the people HN enjoy using java as a webserver (lang-wise, scaling-wise, etc)?
I mostly like Java, and find a lot of the criticisms to be somewhat misguided, or reducing to quibbling over minutiae. But the Java ecosystem has a lot going for it, and despite how some people think "enterprise-y" is a pejorative, a lot of those "enterprise" features are actually very handy when you're, well, building a serious enterprise solution. Sure, if you're building the n thousandth MVP of a new cat-picture-sharing site, you don't need Java. But if you're building Amazon.com (the ecommerce side, not AWS) you might just find that JTA, JMS, JMX, JAX-RS, and some of the other "enterprise-y" stuff in Java is pretty fucking useful.
From a scalability standpoint, using modern appservers, Java scales horizontally just fine. And since Java runs on just about everything from watches to IBM zSeries mainframes, it also scales vertically pretty well.
All of that said, I prefer to do my actual coding in Groovy, as opposed to "pure" Java, but Groovy is almost a strict superset of Java, just with nicer syntax and some new features. But whether you're using Groovy or Java, everything I said above still applies, since you're still part of that overall JVM ecosystem.
Groovy's much slower than Java. The statically typed mode shipped in Groovy 2 a year ago was written by one lone programmer they brougt in, is still buggy, and isn't even used in the Grails codebase afaik.
Ive enjoyed writing code in scala, not until I compile it. It takes a long to compile. I agree with you, java is not enjoyable but we cannot deny the fact it still gets the job done.
That used to be true earlier, but the compile times in Scala are pretty good these days. Also I hear that a faster compiler is expected with the 2.11 release. Incremental compilation in Eclipse is already real-time.
But in general, IMO, compile times shouldn't be a major factor in choosing a language; expressiveness and run-times are more important.
That's only partially true. Compile times are absolutely a factor in development time for the same reason that how long your test suite takes to run is a factor. A faster feedback loop can shorten dev cycles. If nothing else, it's more fun to have faster compiles.
This is one reason Go is so appealing to many people. The compile times make it "feel" like ruby or python or php in terms of "hit refresh and the change is there" style of development. That is a huge difference from, hit save and wait a minute for my java project to compile, and push out to tomcat a minute later. Even with JRebel the best I've seen is a 2-5 second page change refresh cycle in Scala and a minimum 5 second test suite reload time using SBT.
Scala is a beautiful language, but compared to Go, it's a very slow dev cycle.
> compile times shouldn't be a major factor in choosing a language
Not sure about that, I'm using C# to write office plugins and it takes forever to start up each time. Often I forget what I'm supposed to be looking at by the time it's started.
Memory is the dominant cost factor when you rent a server, but my main issue with Java's memory usage is that a single (Oracle) VM instance becomes incresingly unusable above 4GB of RAM due to garbage collector pauses. If you can distribute your work over many VMs that's fine, but if the application needs a lot of data in memory then Java just isn't a viable solution. At least not the Oracle VM and Azul is too expensive.
I had looked at Spark a couple of weeks ago. I'm looking for a lightweight service-y sort of framework which just happens to have a good HTTP service available out-of-the-box. My application does back-end processing and coordinates a bunch of data feeds, thick-client HTTP requests, background processing, etc. all together. Spark was too web-centric (not a bad thing, just not what I need). OSGi was an attempt to be what I want, but its requirement of classpath isolation (a good idea conceptually) is onerous in practice. Right now, I'm using a homespun amalgam of Grizzly, Guice, and java.util.concurrent (for thread pooling), and other stuff. I really didn't want to build my own container. I'm intrigued by Apache Karaf, but OSGi is a huge pill to swallow (If you haven't debugged OSGi classloading issues, you'd be in for a treat).
In a nutshell, I want a service lifecycle container which allows me to write small, lightweight, modular services which depend on each other. The container should provide for cross-cutting concerns like monitoring, management, configuration, logging, auditability (I have concrete definitions for these things -- they're not just abstract biz-speak to me). HTTP should be an out-of-the-box, optional module. A service which exposes another service via a RESTful interface and depends upon the HTTP service should be another. For my application, services which listen to multicast data streams are just as important interfaces to the world as JSON-over-HTTP-via-REST. I want to write the HelloWorld method body and be able to do stuff like: expose it via a RESTful interface, invoke it every N seconds, inject an interface exposing the HelloWorld contract into other services, etc. When I want to know how my HelloWorld service is performing, there's a pre-built web interface which provides New Relic-esque views. I'd like to capture audit trails of the transactional flows through my services from an origination point (HTTP call, scheduled job, etc.) so I can translate failures, poor performance, usage rates, etc. into meaningful information (I wrote a poor man's version of this myself, and it's been quite useful).
Does anything like this exist? I sure can't find it. Modern JBoss (now Wildfly) might actually be closer to my requirements than I think. Perhaps I should look at the work they're doing on Version 8.
Using Grizzly/Netty as the core comm component seems like a good idea. Jersey integrates will with Grizzly, I think.
Dropwizard packages together Jersey on top of Jetty with good monitoring, but doesn't take care of other stuff like multicast. Nothing prevents you from adding Netty/Grizzly into the mix, though.
Actually, the modularity, composability and cross-cutting concerns you mention suggest Spring – not lightweight by any means, but neither are your requirements :)
Hate to say it but Karaf does fit the bill. Use the right mvn plugins and it's mostly just boilerplate. I work with it every day and it's generally not the painful experience you think it is.
I've been using Dropwizard. It provides a nice way to lifecycle manage other objects, so I've used it as a platform for Thrift services with Jersey resources serving debugging information.
It's kind of a bastardization, but we have a pretty good mix of HTTP and not, so it's nice to standardize.
Have people dropped the 'com' from java projects now? Not arguing in favor, the whole thing is ridiculous to me (src/main/com/actual_files). Just curious.
It would actually be src/main/com/organization/project/actual_files
And there are good reasons for that - naming packages after internet domains prevents namespace clashes and is consistently used by most Java projects.
It's actually projects that diverge from this convention that stand out like a sore thumb, and many that did have adopted it eventually, like JUnit.
Depends on the dependency management they want to support. If you want to get your package into maven central making it easy to use, you seem to still have to own the domain in reverse order. aka if you want to publish a package with a com.foo.* you need to actually own foo.com.
It is a nice one. I use Jelastic(www.jelastic.com) for my startup. What if we can have the same functionality there integrated. But this is needed at least the microframeworks are nice. Thinking that the same kind of thing can be also achieved with he framework integration in Jelastic.
It really bugs me that they decided to clone the Sinatra README page, keeping most of the docs on one giant list instead of a more traditional multi-page doc approach. See here: http://www.sparkjava.com/readme.html
Lastly, it appears they're using GitHub for actual code, and, while they have a Github wiki created, it has no information.
I wish I could stress just how important it is to have all of the docs in one centralized location. Somewhere along the line, one of the five places they have examples will get out of date, and it'll be difficult to play spot the differences when it's replicated everywhere.
Okay. I am holding the idiot ball here: How can we deploy an app developed with spark? What are our options? Heroku? AWS? I haven't seen anything regarding to deployment in the documentation.
At the bottom of http://www.sparkjava.com/readme.html there are 2 options, an embedded web server (Jetty) and a configuration snippet for a standard web.xml file.
Its most notable implementation is perhaps Jersey (https://jersey.java.net/documentation/latest/getting-started...), which is used, for example, by Dropwizard (mentioned in another comment).
Some of these implementations include important features like health and performance monitoring.