SpringSource Bag 'o Swag
We're giving away bags 'o swag! To get some, just follow the instructions on the SpringSource Bag o' Swag website! Oh, did I mention that you could also win a free ticket to SpringOne2GX 2013? Don't delay, act now! We've given away a lot of cool stuff, already!
The Apache Hadoop Ecosystem, Visualized in Datameer
I just found this amazing graphic visualizing the Hadoop ecosystem in Datameer on the Cloudera blog.
Multi Client Development with Spring Webinar on March 14, 2013
I'm going to be doing a webinar for SpringSource on March 14th, 2013, called Multi Client Development with Spring (and Spring MVC). The webinar will feature an introduction to Spring MVC's basic component model, as well as the principles of REST. Once we've introduced Spring's REST support, we'll look at how to take your application to your users by building clients that your users want to use with Spring Mobile, Spring Android, and HTML5.
Be sure to register now and bring questions, ideas, etc. I look forward to seeing you at there, and we'll look at some of the amazing support Spring offers for building best-of-breed web-centric, RESTful applications.
Spring MVC Performance FTW
We've all seen Matt Raible's awesome talk comparing web frameworks with each other. He routinely gives this talk, often updating it as new technologies emerge. More often than not, Spring MVC and Grails emerge as leaders. These sorts of talks of course never have a conclusive winner, but, as I say, more often than not, Grails and Spring MVC emerge near - or at - the top of the stack in terms of community, ease of use, lines of code, performance, features, etc.
For a very detailed dissection of performance, you might check out this talk comparing web framework performance. Matt's talk builds on the data amassed from that talk.
My Post on Spring at China Scale
|
| Hey guys I put up a post on the SpringSource blog, Spring at China Scale: Alibaba Group (Alipay, Taobao, and Tmall) which details some of the stuff I learned when I visited TaoBao, TMall, Alipay, etc., under the Alibaba group in December, in China. Check it out! |
Validating with Spring MVC, JSR 303, and BindingResult Arguments
TL;DR: In your Spring MVC controller handler method, make sure that the BindingResult argument is immediately after the command or model argument.
Ran into something of an odd behavior in my Spring MVC application:
The following code works fine: requests come in and if there are request attributes whose names map to JavaBean-style properties on the SignInAttempt POJO, an instance of that POJO is created and populated with the values from the request. This POJO is then made available in the Spring MVC controller methods that depend on them, like this one below.
If there is a JSR 303 @Valid annotation on the POJO, as in this case, Spring MVC will validate that the POJO itself complies with the constraints. If it doesn't, it will bind the errors it finds in the BindngResult object, as message keys (like Email.signInAttempt.username) which can be used to display errors to the client.
public String signin(@ModelAttribute @Valid SignInAttempt signInAttempt, BindingResult result, Model model)
What won't work so well is if you bind position the BindingResult anywhere besides immediately after the model / command / POJO itself as we have above. Thus, all of the following configurations will fail with an exception.
public String signin(@ModelAttribute @Valid SignInAttempt signInAttempt, Model m, BindingResult result )
public String signin(@ModelAttribute @Valid SignInAttempt signInAttempt, @RequestParam String username, BindingResult result )
// etc.
So, takeaway and rule of thumb: all model object arguments must be succeeded by a
BindingResult in your Spring MVC request handler method.
How to Deploy Cloud Foundry to Amazon Web Services using BOSH
Today I was fortunate enough to learn from Dr. Nic as he introduced his open source utility, bosh-boostrap, which makes shortwork of the chores of setting up and deploying BOSH and Cloud Foundry on AWS. Largely, the steps are reproduced and available on his tutorial which he's put online online.
BOSH is the orchestration manager for the underlying IaaS component - vSphere, Amazon Web Services or Open Stack.
BOSH in turn knows about releases, the makeup of some distributed systems, like Cloud Foundry. Cloud Foundry in turn has lots of moving parts and components, like PostgreSQL, and NATS - the Cloud Foundry message queue.
Since BOSH deploys its own packages of components like PostgreSQL, there is a lot of compiling. This process takes a few hours with Dr. Nic's excellent utility. Most of that, happily, is just wait time as you wait for things to compile and upload or download. If you weren't using the bosh-bootstrap utility, however, you'd spend a lot more time setting things up and configuring things. BOSH is very flexible, and overwhelming. bosh-bootstrap is opinionated, concise, and surfaces only the things it couldn't possibly devine by itself.
Anyway, feel free to ping Dr. Nic or me on Twitter if you have questions. It was really cool to see it all startup and then be able to deploy applications to it.
A few words of caution and advance notice:
You'll need an Amazon Web Services account. The utility will leave you with 5 very expensive nodes on Amazon Web Services as well as a lot of configured storage. You should stop the instances and storage or just outright delete them when you're done if you don't intend to keep it running.
Also, you'll need to have a domain you can point to this. During this process you'll be given an IP, and you'll need to create an A-name record (for *) in your DNS configuration for your hostname and point it to that IP.
I got the application presented here on this Pre Shaved Yak blog post up and running at starbuxman.org, and a colleague got it working on his private instance as well.
Coffee Drinks in China
My amazing adventure in Shanghai, China is almost up. I return home to the US on January 31, and must wind down my time here. As part of that, I need to finish my amazing stash 'o iced coffee drinks that I've only found here in China. I don't know if you know this about me, but I love coffee. And yes, before you ask, that really is the bedspread they gave me at this hotel in Shanghai. @_@
On Damien Katz' "The Unreasonable Effectiveness of C"
I loved Damien Katz' blog on The Unreasonable Effectivenes of C.
I also really liked commentor Mark Peskin's input on the news re-cap of Damien's blog over on InfoQ. I just wanted to offer my 2c from the perspective of someone who's done enough C to have 2c.
One thing that Damien noted is that it's rare to see really large, comprehensive framework-like APIs in C. As long you as build small, singly-focused APIs with light domains (a few typedefs / structs and functions as the 'contract') then it's very easy to 'export' the library and re-use it. This, I think, is a sweet spot for C. I would never write something in C for performance, but instead because it's simply easier to do certain things in C (kernel programming, embedded programming, anything working with the hardware, anything relying on APIs that aren't both established and widespread enough as to have warranted an cross-platform 'abstraction' in a higher level language like Java, Ruby, Python etc).
I would also try to not write a full blown system in C, simply because it doesn't 'scale' for large projects. The large projects that do use C end up re-inventing a lot of things (like 'objects' and namespacing). IMHO, there are very few domains that truly need to be in C the whole way through. Some very notable exceptions are systems level components like operating systems (Linux) or UIs like GNOME, of course. But for applications, it's easier to build out in a higher level language and 'integrate' with lower level APIs where the higher level language and platform has gaps. Java has many such 'gaps,' though some've been slowly addressed in the last decade as APIs have become commonplace across many different operating systems: event driven IO, file system notifications, file permissions and metadata, etc.
Mark makes a great point about how to integrate C libraries and modules. He suggests JNI sucks, and to use messaging. I am a big fan of messaging. Fundamentally, successful use of messaging and successful use of JNI both require the same thing: you need to simplify the exported API drastically.
When using JNI, I try to never 'leak' any complex C types into my java API and vice versa, always communicating through numeric types and char* -> jstrings. Even if the native code I'm exposing is C++, I'll still use the C-flavor of JNI (not C++) because it forces this canonicalization that's favorable to interop. If you keep the surface area of the C API very light, and try to avoid threading, it's easy to make it work as a native extension via Java JNI or CPYthon or MRI Ruby, etc.
Once you've gone through this process, then exposing the C API via messaging is easier because the message payloads between two systems can't, by definition, be much more complicated than the surface area of the C library. Of course, if you're using messaging, that means either writing messaging code in C, or exposing the C library to some higher level language and doing the messaging there. The nice part about messaging is that insulates your higher-level language code from your C code which - let's be honest - might be flakier than your Java code. I still won't link code written against the imagemagick C APIs directly to my application! There is some black magic in that library...! If the C code dies, the messaging system absorbs the requests until another node running the C code can pick up the slack. On the other hand, if you really are using C for performance, then messaging introduces at least a network hop, not to mention another component in the system, and you might lose any gains you made by writing it in C. In this case, it is possible to use write stable, well-behaved JNI or native extensions, but this again requires keeping the surface area small and understanding the pre-conditions nad post-conditions. No threads. Don't pass around pointers to complex objects between C and Java. Make sure you understand who's supposed to clean up memory, and when.