The Angular Mini-Book is a
guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and
deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.
Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with
Spring Boot and use security best practices like HTTPS and a content security policy.
This book shows you how to build an app with JHipster, and guides you through the
plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks
so you understand the underpinnings of your great application.
In February 2012, Trish and I traveled
to
Stockholm on Icelandair. We were immediately impressed with the
airline's
excellent service. Trish was also a bit miffed that we had a layover in Iceland without an opportunity to get out
and see the sites. You see, Iceland is a Photographer's Paradise, and she's the
best photographer I know.
This year, when planning our trip to Devoxx
France, I set out to correct this missed opportunity. Since Icelandair now flies direct from Denver, and offers
free stopovers, our planning was easy.
The conference was in Paris; one of the most magnificent cities to photograph. Trish has some great photos from 2011.
She'll be showing many of these photos at an upcoming exhibit at Paris
on the Platte in Denver. However, she wanted more.
We arrived in Paris for Devoxx France on Tuesday, March
26th. The first day's excursion started with visiting the Latin Quarter, the
Panthéon and Notre Dame.
We had a nice dinner that evening while watching the Fútbol match between France and Spain.
On Wednesday, we hung around the hotel in the morning, then took the metro to
La Basilique du Sacré Coeur de Montmartre and Moulin Rouge.
From there, we journeyed to the Eiffel
Tower for a hike. We climbed the stairs to the second floor and enjoyed the spectacular view.
Wednesday evening, we attended the Devoxx Speakers Dinner. We had a great time chatting and drinking wine with Martin Odersky, Guillaume Bort, the many Nicolas', James Ward and Josh Long.
On Thursday, I delivered my talk on Comparing JVM Web Frameworks in the early afternoon and did
Play vs. Grails Smackdown with James Ward in the evening. I published an
article about these talks
the next day.
While I was talking about frameworks, Trish was galavanting around Paris taking some amazing photos.
Thursday night, we had a wonderfully authentic French dinner with many of the folks from the conference. Around
midnight, Trish captured the beauty of Les Invalides.
On Friday, we slept in a bit and then headed to the airport for our flight to Iceland. A few hours later, we were
snuggled into the cozy bar at Hotel Reykjavik Centrum. A few hours after
that
and we were bouncing up and down on a Super Jeep tour to see the Northern Lights.
Our
driver kept telling us "if you believe, it will happen". And boy oh boy, did it ever. The green and purple lights
dancing in the sky overhead were mind-blowing!
Saturday came quickly after a late night, and we opted for a scenic tour of the area by helicopter.
Easter Sunday was our last day in Iceland and we enjoyed most of it at the Blue
Lagoon. Despite the plethora of tourists, the hot springs, saunas and cold beer were a lovely way to prepare for
the long road home.
Visiting Iceland and photographing the Aurora Borealis
was an awesome experience. Speaking at Devoxx France, photographing Paris and having lots of good times with new
(and old) friends was equally delightful. For more pictures of our travels, see my Paris and Iceland
Album or Trish's Devoxx France,
Iceland or Northern Lights albums.
This week, my lovely fiancé and I traveled to the City of Light. Our journey was designed around some speaking engagements at Devoxx France. Devoxx is one of my favorite conference franchises and Devoxx France has been special to me ever since the Devoxx (Belgium) I spoke at in 2011.
2011 was the year I spoke about my experience with Play, Scala, CoffeeScript and Jade. I wrote the presentation on my flight over, composed the demo video the night before and made it all happen in the nick of time. Of course, this was after 120 hours of research and preparation, so the presentation composition process had all the data I needed. You can imagine my sense of relief after pulling off that talk and getting an enthusiastic applause from the audience for my efforts.
One of the first audience questions I received was from Nicolas Martignole, asking if I'd speak at Devoxx France the following year. I whole-heartedly agreed to do it and was excited for the opportunity. It was with great disappointment that I later found out I couldn't attend Devoxx France in 2012. My client didn't like me taking so much time off and I agreed to scale my two week vacation back to 1 week. This year, I was determined to go, so I submitted some of my favorite talks: Comparing JVM Web Frameworks and The Play vs. Grails Smackdown with James Ward. I was extremely pleased when they both got accepted.
Side Story: I met Martin Odersky shortly when he sat down next to me for the Java Posse presentation in Belgium in 2011. After shaking his hand and introducing myself, I had to politely ask him to leave because it was Trish's seat. Talk about awkward; but Martin was very gracious and promptly found a new seat close by.
Comparing JVM Web Frameworks
Both talks required a bit of updating. For Comparing JVM Web Frameworks, I started reading The Paradox of Choice and found many parallels to the agony that developers experience with choosing a web framework. I described how I didn't think good framework decisions were based on the many, many features that frameworks have, but often on pre-defined constraints. There's those lucky developers that get to choose a Full Stack Framework because they're doing greenfield development. Then there's those that want a better Pure Web Framework that replaces something (e.g. Struts) that's not satisfying their needs. And lastly, there's those that've found it possible to leverage a SOFEA and use a JavaScript MVC framework with an API Framework on the backend. I don't think it makes sense to compare all web frameworks and I tried to use these pre-defined constraints (language, platform and application type) argument to separate into categories and help make choosing easier.
I took out the parts of the presentation that've pissed people off in the past - particular the JSF bashing by James Gosling, the Rails gushing from Craig McClanahan and the Pros and Cons sections of each framework. I added the history of web frameworks and research from InfoQ and devrates.com.
The best part of the JVM Web Frameworks talk was the audience's reaction and enthusiasm. Devoxx always seems to attract passionate developers and Devoxx France was no different. Developers packing the room, clapping after your intro, laughing at your jokes, signifying that they agree with you about JSF. As a speaker, it's an unbelievable experience.
You can view my Comparing JVM Web Frameworks presentation below or on Slideshare.net.
Play Frameworks vs. Grails Smackdown
To prepare for James Ward and my Play vs. Grails Smackdown, we had a number of goals. First of all, we wanted to update our apps to use the latest versions of each framework. I documented what it took for Grails, James just checked in his code to GitHub. It was interesting to see that Grails 2.0.3 -> 2.2.1 caused a number of issues with testing, while Play 2.0.3 -> Play 2.1.0 required API changes, but nothing for tests. Secondly, we updated all the stats for our pretty graphs and ran load tests again.
This is where the fun started. On Tuesday evening, I decided to challenge the notion that Play was twice as fast as Grails. James had proven this with Apache Bench tests. With Play 2.0 and Grails 2.0 (last summer), we clocked Play at 251/requests per second and 198 for Grails. After upgrading each app to the latest releases, we found the numbers to be 233/second for Play and 118 for Grails.
However, Apache Bench only tests until the first byte is received. Since I've done a lot of browser optimizations recently, I fired up whichloadsfaster.com, captured a screenshot and added it to our presentation. The next day, James added a CDN and a bunch of caching to his app and re-ran his AB tests.
Now he was smoking Grails, so I added a CDN and caching as well. However, the best I could do was just over 1000/requests per second, while he was around 2200/second. When he ran live tests during our talk, Play was around 2800/sec and Grails was around 900.
It was great to see how much better performance we could get with caching and a CDN. The best part is this should be available to most applications, not just these frameworks. By adding a CDN (we used Amazon CloudFront) and caching, we were both able to 10x the performance of our apps. You can find our presentation here or view it below.
Summary
This was a very enjoyable conference to attend as a speaker. First of all, it was in one of the most beautiful cities in the world, but it's also a very special place for Trish and I. We got engaged just outside of Paris in Versailles after the last Devoxx conference I spoke at. Trish has some amazing photos from that trip. Secondly, the Devoxx conference attracts a special kind of developer - one that is passionate about and eager for knowledge. Lastly, speaking with my good friend James, in an exotic city about something we love - that was special. Asking for beers and having them brought to us at the start of our Smackdown. That was magical (thanks Nicolas!).
To all the Devoxx organizers and crew - well done on a great show!
In preparation for my Grails vs. Play Smackdown at Devoxx France next week, I recently upgraded my Grails version of Happy Trails from Grails 2.0.3 to Grails 2.2.1. I ran into a few issues along the way and figured I'd document them here to help others out.
Fixing the source The first issue I ran into was Spock and Groovy 2 incompatibilities.
| Resolving plugin JAR dependencies
| Error WARNING: Dependencies cannot be resolved for plugin [mail] due to error: startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/Users/mraible/.grails/ivy-cache/org.spockframework/spock-core/jars/spock-core-0.7-groovy-1.8.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 0.7.0-groovy-1.8 is not compatible with Groovy 2.0.7. For more information, see http://versioninfo.spockframework.org
I posted the problem to StackOverflow and got a response almost immediately. While this pull request helped me quite a bit, it was ultimately caused by my vision: I had two "geb-spock" dependencies listed in BuildConfig.groovy with different groupIds.
At this point, I also moved all my plugin dependencies from application.properties to BuildConfig.groovy.
The next problem I ran into was a unit test and functional tests failing. The unit testing issue was caused by my Direction model not being in the tests @Mock annotation. After I added it, validation kicked and I recognized my test was invalid. I added @Ignore and continued.
The functional test seemed to be seemed to be caused by Geb and it trying to use the Chrome Driver. One of my tests didn't work with the default HtmlUnitDriver, so I used the ChromeDriver for the one test.
| Running 11 spock tests... 6 of 11
| Failure: signup as a new user(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.WebDriverException: Unable to either launch or connect to Chrome. Please check that ChromeDriver is up-to-date. Using Chrome binary at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.66 seconds
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.2', java.version: '1.7.0_04'
Driver info: org.openqa.selenium.chrome.ChromeDriver
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:111)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:115)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:161)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:107)
at happytrails.AuthenticatedUserSpec.signup as a new user(AuthenticatedUserSpec.groovy:25)
Even when running "grails -Dgeb.env=chrome test-app", this still happened. This was caused by the fact that I had GebConfig.groovy in test/functional/happytrails. Move it to test/functional solved the problem. I also discovered that I know longer needed Chrome to get this test to pass. Apparently, the HtmlUnitDriver has issues with Grails 2.2, but it seems to work for me.
After getting the Geb configuration fixed, I ran into a functional test failure:
| Running 11 spock tests... 5 of 11
| Failure: click signup link(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.ElementNotVisibleException: Element must be displayed to click (WARNING: The server did not provide any stacktrace information)
Even though I could see the "signup" link when I ran "grails run-app", I could see that it didn't show up when running tests in Chrome. This turned out to be caused by an extraneous <div class="nav-collapse"> I had in my main.gsp. Removing it solved the problem. It's strange that this never showed up with Grails 2.0. My only guess is that Geb someone didn't look at the visibility of the element.
The last testing-related issue I ran into was a InvalidElementStateException:
| Running 11 spock tests... 7 of 11
| Failure: add new route to region(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.InvalidElementStateException: Element must be user-editable in order to clear it. (WARNING: The server did not provide any stacktrace information)
I was able to fix this by changing AddRoutePage.groovy from:
And then referencing name, distance and location accordingly (form.name, etc.) in AuthenticatedUserSpec.groovy.
CloudBees
After I had everything working locally, I logged into Jenkins on CloudBees. Since I hadn't used it in a while, I had to wait a bit while my Jenkins server was re-commissioned. Once it was up, I tried to select Grails 2.2.1 to build with, but found it wasn't available. After a tweeting this, I learned about Grails Wrapper, found that the latest Grails Jenkins plugin supported it and got everything working. I later discovered that CloudBees does support Grails 2.2.1, I just needed to setup another Grails installation to automatically download and install 2.2.1.
Heroku
The last two issues I ran into were with Heroku. Since I was upgrading everything, I wanted Grails to build/run under Java 7 and use Servlet 3. I changed the appropriate properties in BuildConfig.groovy, configured Heroku and deployed. No dice.
Error Compilation error: startup failed:
Invalid commandline usage for javac.
javac: invalid source release: 1.7
Usage: javac
use -help for a list of possible options
Sidenote: I tried building with Java 8 on CloudBees, but discovered the searchable plugin doesn't support it.
Compile error during compilation with javac.
/scratch/jenkins/workspace/Happy Trails - Grails 2/work/plugins/searchable-0.6.4/src/java/grails/plugin/searchable/internal/compass/index/DefaultUnindexMethod.java:94: error: reference to delete is ambiguous
session.delete(query);
^
both method delete(CompassQuery) in CompassOperations and method delete(CompassQuery) in CompassIndexSession match
As far as Servlet 3, it was pretty obvious that the Jetty version Heroku uses for Grails doesn't support it. Therefore, I reverted back to Servlet 2.5.
java.lang.NoClassDefFoundError: javax/servlet/AsyncContext
at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)
I sent the Java 7 issue to Heroku Support a few days ago but haven't heard back yet.
Summary
While upgrading Grails from 2.0 to 2.2 wasn't as easy as expected, it is understandable. After all, Grails 2.2 ships with Groovy 2.0, which has a bunch of new features itself. All the issues I ran into were fairly easy to solve, except for Java 7 on Heroku. But hey, what do you expect from a free hosting service?
If you're at Devoxx France next week, I look forward to sharing our research on Grails 2.2.1 vs. Play 2.1.0.
On October 30th, 2012, shortly after I'd woke up, I received an email from my old friend Jess (of Jess and Lili's Legendary Wedding). Its subject: "Wanna go to Mexico?"
We are taking a trip to Mexico Feb 16-24 with some friends from here and have one spot that just came open in the house we are all renting together. It's a sweet spot, 1 hour north of Puerto Vallarta. It has seven bedrooms each with own bathroom, a cook, private beach and nice pool, link below. Works out to about $1100 per week per couple.
... http://www.laspalapas.tv/home.html
As you can imagine, I was immediately enticed by the opportunity. I checked my schedule, verified they had high-speed internet and responded We're IN! a couple hours later.
A couple weeks ago, we embarked on this journey and had a great time. The house was awesome, the company was fantastic and the views were spectacular. Not only that, but the town we stayed in (Chacala) was very authentic. No resorts, hardly any paved roads and nary a tourist in sight.
We didn't take our kids, but a few families did, resulting in 19 people total. Everyone got along swimmingly, the home-cooked meals were wonderful and the weather was beautiful.
For the most part, we didn't do much throughout the week. I had to work, so I spent my days on the computer with an occasional break to play a game of volleyball. I experienced the same issue I did in Maui and Kauai last year, where my MacBook Pro couldn't find my hard drive. Yeah, it's a first-world problem: my laptop tries to stop me from working when I'm on a beach. Luckily, I had a backup (external) hard drive that I could plugin and work from.
We did a whale watching and snorkeling trip on a Catamaran one afternoon. We didn't get any good whale pictures, but we had many sightings.
I only ventured into Chacala once, but found it to have a lovely beach, good music, and tasty restaurants.
Thanks to Jess and everyone else for inviting us to this magnificent place in Mexico. We had a great time, made a lot of new friends and thoroughly enjoyed ourselves.
I've been comparing web frameworks ever since 2004. It was the first time I'd ever proposed a talk for a conference. ApacheCon was in Vegas that year and my buddy Bruce suggested I speak at it. I submitted the talk, got accepted and went to work learning the frameworks I was talking about. At the time, I had a lot of Struts experience and I'd made a good living learning it, consulting on it and blogging about it. However, there was a new kid on the block (Spring MVC) that was garnishing attention and some other frameworks (WebWork and Tapestry) that had a lot of high praise from developers. I was inspired to learn why so many people hated Struts.
Fast forward 8 years and I'm still comparing web frameworks. Why? Because there still seems to be a large audience that's interested in the topic. Witness InfoQ's Top 20 JVM Web Frameworks, which was one of their most-read articles for two months in a row. One of the beauties of the Java Community is that it's very diverse. There's tons of folks that are part of this community and, like it or not, several folks that are former Java Developers. However, these developers still seem to maintain an interest in the community and it's still one of the largest pools of talent out there. Java is still quite viable and only seems to be getting better with age.
So the topic of web frameworks on the JVM is still hot, and I still like to write about it. For those of you still enthusiastic about the topic, you're in luck. The two best websites for the Java Community, InfoQ and DZone (formerly Javalobby) are still very interested in the topic too!
I wrote my first year in review blog entry way back in 2005. That means this year's is number 8. Since they keep getting longer every year, I figured I'd try something different this year and use sections similar to Remy Sharp.
I spent the entirety of the year with one client: Taleo. Oracle bought them in February. In June, the transition to Oracle happened. My tasks and projects haven't changed much since the transition, but it has been a real pain to get paid on time. My contract with them is through the end of May. I hope to take July off (to get married) and August off (to honeymoon) and start a new gig in September.
I did minimal Java work throughout the year and spent most of my time doing CSS and JavaScript. I love doing front-end work much more than back-end, so day-to-day, it was very satisfying.
One of the most important things when developing webapps is to make them fast. With AppFuse, we've tried to incorporate many of the 14 rules for faster-loading websites. We had a gzip filter before it was cool (2003) and replaced it with the one from EhCache. However, users experienced issues with both of these, both with XFire/CXF and WebWork/Struts 2 and JSPs. Because of these issues, we disabled gzipping a few releases ago.
This article is designed to show you how you can make your AppFuse webapp faster, without modifying any code. The good news is this applies to any webapp that you can deploy behind Apache.
Last Friday, I sent an email to the good folks at Contegix to see if they could install mod_pagespeed on the Apache server that sits in front of *.appfuse.org. My goal was to improve the YSlow and PageSpeed scores of the apps hosted on demo.appfuse.org. I discovered they were getting a dismal score of 24 and figured we could do a lot better. mod_pagespeed speeds up your site and reduces page load time by automatically applying web performance best practices. It seemed like an easy solution.
Unfortunately, we were unable to use mod_pagespeed. From the guys at Contegix:
Attempting to install mod_pagespeed as you requested, we find that it requires Apache httpd 2.2 and libstdc++ 4.1.2, both of which are unsupported in RHEL4. To get mod_pagespeed to work on your present operating system basically means re-rolling the core components, which would make them unsupported. I'm afraid mod_pagespeed is simply not an option on your present configuration.
Since I still wanted to improve performance, I opted for another route instead: using mod_deflate (for gzipping) and mod_expires (for expires headers). I also turned on KeepAlive as recommended by PageSpeed Insights.
mod_deflate mod_deflate was already installed in Apache (version 2.0.52), so all I had to do was configure it. On RHEL4, Apache is installed at /etc/httpd and there's a conf.d directory that contains all the configuration files. I created a file at /etc/httpd/conf.d/deflate.conf and populated it with the following:
At first, I had separate lines for all the different content types (as recommended by this article). The Contegix support crew figured out the solution (everything needed to be on one line) in 14 minutes, updated the config and verified it worked using an http compression testing page.
mod_expires mod_expires was already installed, so I added a config file at /etc/httpd/conf.d/expires.conf. I used this howto and asked Contegix for help when it didn't work. Their response took quite a bit longer this time (49 minutes), but they once again figured it out:
It appears that FilesMatch does not like to play will JkMount. It does work using content type.
My final config for expires.conf:
<IfModule mod_expires.c>
ExpiresActive On
<FilesMatch "\.(jpe?g|png|gif|js|css)$">
ExpiresDefault "access plus 1 week"
</FilesMatch>
ExpiresByType image/jpeg "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType image/gif "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
</IfModule>
I used "1 week" because we're changing things quite a bit right now and we haven't integrated resource fingerprinting yet.
KeepAlive The last thing I did to improve performance was to turn on KeepAlive by editing /etc/httpd/conf/httpd.conf and changing Off to On.
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
Summary As a result of these changes, our PageSpeed score went from 24 to 96 and YSlow went from a 90 to a 98. When I started this experiment, I was only trying to fix demo.appfuse.org. However, it also improved the speed of all the other *.appfuse.org sites, including Confluence, Bamboo, JIRA and FishEye. Thanks for all the help Contegix! There's a good chance you've given me back a few minutes in each day.
There is one little thing that does bother me in those presentations, and that's your fairly obvious bias against JSF. ...
If you are presenting yourself as, more or less, an authority on comparing web frameworks, then having a fairly obvious biased against one of them is just peculiar. I, all of my team, and various clients distrust your ranking of JSF. We do look at your data if the choice is between other frameworks, but as soon as JSF comes into the picture we just look elsewhere.
I'm not really sure where this bias comes from. Yes, JSF 1.0 sucked and 1.2 was only marginally better, but 2.0 is really cool and productive and there are SUPERB component and utility libraries now like PrimeFaces and OmniFaces. As a researcher of this topic I think you should keep up the date and not stick to some old grudge.
This is true, I am biased against JSF. It all started with my first JSF experience back in August 2004. If you remember correctly, 2004 was a big year: JSF 1.0, Spring 1.0 and Flex 1.0 were all released. The "AJAX" term was coined in early 2005.
Most of my issues with JSF come from having maintained an application built with it since 2004. If I were to start a new application without any legacy migration issues, I imagine it wouldn't be as difficult. However, if you compare it to Struts 2 and Spring MVC, I've had little-to-no issues upgrading those applications over the years.
Also, I'm not just biased against JSF, but most component-based web frameworks. Just ask the Tapestry and Wicket folks. They've felt my criticisms over the years. My reason for preferring request-based frameworks like Struts 2/Spring MVC and Grails/Play has been because I've never seen the appeal in component-based frameworks. Often I've found that their components are just widgets that you can get from any decent JavaScript framework. And chances are that JavaScript framework can work with any web framework. Also, I've worked on a lot of high-traffic web applications that require statelessness for scalability.
I see the value in component-based frameworks, I just don't think components should be authored on the server-side. Most of the Java-based component frameworks require 2+ files for components (one for the component, one for the view, possibly one for the config). I love GWT's component concept in that you can just extract a class and re-use it. With JS frameworks, you can often just include a script. These days, when I think of good component-based frameworks, I think of jQuery UI and Twitter Bootstrap.
All that being said, there's a lot of folks praising JSF 2 (and PrimeFaces moreso). That's why I'll be integrating it (or merging your pull request) into the 2.3 release of AppFuse. Since PrimeFaces contains a Bootstrap theme, I hope this is a pleasant experience and my overall opinion of JSF improves.
In other component-based frameworks in AppFuse news, Tapestry 5 has gotten really fast in the last year. I imagine this is because we have a Tapestry expert, Serge Eby, working on it. And we're planning on adding Wicket in the 2.3 release.
So even though I prefer request-based frameworks with REST support and Bootstrap, that doesn't mean everyone does. I'll do my best to be less-biased in the future. However, please remember that my view on web frameworks is as a developer, not an analyst. And aren't developers supposed to be opinionated?
Back in early October, InfoQ.com published a community research article titled Top 20 Web Frameworks for the JVM. Their goal seemed to be fairly simple:
Using the new community research tool, we at InfoQ want to get YOUR opinions on the relative importance and maturity of a variety of web frameworks that are targeted for the JVM. Please vote by dragging each practice across two dimensions – how important is the framework relative to the other frameworks, and how much is it actually used in real teams and projects.
When I first saw this article, I noticed some strange web frameworks listed. Namely, Netty, SiteMesh and Spark. I haven't heard of many folks using Netty for a web framework, but I'm sure it's possible. SiteMesh is certainly not a web framework and I've never even heard of Spark. And where is GWT and Vaadin? Regardless of the choices, I went ahead and voted.
Last week, InfoQ posted their top content for October on Facebook.
First of all, it's interesting to see that JVM Web Frameworks is still a hot topic for developers. Whenever I do my Comparing JVM Web Frameworks talk at conferences, I always see a few jabs about "he's still doing that talk!?" Yes, it seems strange that a talk I first did in 2004 is still in high demand.
Secondly, I think InfoQ does good in showing how the frameworks ranked and showing their heatmaps. Below are their rankings from 1109 participants.
According to this research, the top 5 web frameworks for the JVM are Spring MVC, Play, Grails, JSF and Struts (I hope those surveyed meant Struts 2, not Struts 1).
In my research from last February (slide 21), I ranked them (with no particular weightings) as Grails, GWT, JRuby on Rails, Spring MVC and Vaadin. So I guess you could say I got 2 out of 5 right (Grails and Spring MVC). Not bad considering InfoQ didn't even consider GWT and Vaadin.
Another intriguing data point in this study is each frameworks' heatmap. For example, below are heatmaps for the top 4 frameworks.
Notice how Grails and Spring MVC are both hotter in the bottom right corner? It seems the community's overall opinions of these two frameworks are more aligned than JSF and Play, which a fair amount of folks rank as hyped and unimportant.
What I really like about this research is it's the community's opinions, visualized. It also confirms that some of my favorite frameworks are still on top. I don't know if JSF belongs as a top framework, however it seems a lot of folks do. I recently thought about removing it from AppFuse, but decided to keep it (at least for the next release). I hope InfoQ does more research projects like this, especially if they get their list of web frameworks right.
I've always enjoyed whitewater rafting. I think the first time I did it was in college and I immediately fell in love. Through the years, I've been on many trips with family and friends. However, it wasn't until this summer that I realized it was something I should do more often. It was Trish's friends, Chris and Bryce, that started it all. They bought a raft last year and we floated down the Colorado River with them a couple times over Memorial Day Weekend. Then we went to Montana and enjoyed a couple days on the Middle Fork of the Flathead with Dr. Barton and a bunch of raft guides. That weekend in July, we realized we'd done more rafting than any other outdoor activities (mountain biking, camping and even golfing). That's when we decided to buy our own.
We had a lot of help in the process of buying a raft. First of all, I sat down with my friend Dr. Barton and made a list of all the things we'd need. The good doctor was a whitewater guide in Montana for 5 years, has rescued trips from the wilderness and has even rafted the Grand Canyon - so I considered him a good source of information. After composing the list of necessary gear, we headed to Down River Equipment on August 26th, the last day of their end-of-season sale. It took us an hour to pick out the raft we wanted (a Pro 140) and gather up all the gear (frame, cooler, oars, dry box/bags, lifejackets, koozies, etc.). We asked them to have it ready by Friday and headed home.
Last Friday, we picked up a raft trailer from Trailer Source an hour before they closed, then journeyed to Down River where Mike (the owner) and Matt (the guy who helped us the previous Sunday) helped us setup our oars and load up our new boat. There was much rejoicing.
Saturday, we took it on its Maiden Voyage on the Colorado River, floating from Radium to Rancho del Rio. According to this page, there were some Class III rapids, but they all felt like Class II. I guided and rowed the boat most of the time while our 7 passengers (and 2 dogs) enjoyed cold beverages, great scenery and relaxing in the sun. It took us a bit longer (4 hours) than expected (2 hours), but we all thought it was well worth it.
Abbie's First Golf Game After a long day of floating on Saturday, we decided to chill on Sunday with a little golf. We split the kids up for the weekend (Jack went with his mom), so we figured the proper way to treat our only child was to take Abbie to play her first real game of golf at Pole Creek. We played 9 holes and both Abbie and I had a great time trying out our new clubs. We received a nice kids golfing tip from someone at the driving range: have them tee off from the 150 marker so they have a chance to par the hole.
The course had a 50% discount for kids and we never saw anyone behind us the entire game. We were especially impressed when the course photographer offered us a framed set of Abbie pics for $15.
We don't know how many more days of rafting we'll get in this year, but next year should be epic. We're hoping to do multi-day trips on the Green River, the Smith River and fly into Schafer Meadows for a journey through the Bob Marshall Wilderness. I grew up only 10 miles from "The Bob" and I've never been in it. I can't wait!