Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book 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.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

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.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Farewell to the 2011-2012 Ski Season

In 2011, I experienced the best ski season of my life. On the Thursday after ski season ended last year, I wrote:

For next year, I think I'll keep my goal at 30 days. If everything works out as planned, we'll have a place in the mountains this fall and it'll be a bit easier to hit the slopes without sitting in traffic.

Everything did work out as planned and we found ourselves in eager anticipation of ski season last fall. We prepped the Ski Shack for lots of visitors by getting queen-sized bunk beds made for the kids. We even got a hot tub installed for Trish's birthday in mid-December.

Hot Tub Installed for Trish's Birthday!

For Christmas, my parents, sister and her wife all flew in and we spent a beautiful evening watching the parade at Winter Park.

Christmas Eve at Winter Park Village

The skiing still wasn't great, but there was enough snow to cover the tubing hills in Fraser. We got some sweet helmet covers from my Mom for Christmas and had a blast with Trish's brother's family over New Years.

Skiing on Christmas Day! Skiing with Wild Animals

The "Training" Park Shredders

The rest of the season was filled with a lot of 4-run outings, where we skied the bare minimum to count it as a day. I can recall only 3 really good days. One was at Steamboat with 11" of powder and lots of knee-deep stashes. The others were at Mary Jane where Trish and I got fresh powder tracks for a good hour.

Yep, the snow was terrible this year. In fact, my favorite lift at Winter Park (Eagle Wind) never even opened. I still managed to get in 33 days, but it certainly wasn't a ski season to reminisce about. I am proud of the fact that Abbie and Jack skied 15 days and never needed a lesson. Trish even taught them how to snowboard one day and they both loved it.

We only made it to 3 resorts this year, a far cry from last year's 9 + a hut trip. However, I don't feel like we missed out because the snow was so bad. Having a condo 15 minutes from the resort certainly helped us get more days in, but I'm willing to bet we skied 10x more hours last year.

Next year, I hope it snows a ton and we get 50 days in. In the meantime, I'm pumped that mountain bike season has started and there's lots of dry trails along the front range. I have two rides in so far this week and hope to get at least 30 days in this summer. With 600 miles of trails just minutes from our Ski Shack, it seems like it should be easy enough.

In other life-related news, I'm driving to Colorado Springs this afternoon to pick out the interior for The Bus. With any luck, MotorWorks Restorations will have it done in a couple months. In the meantime, you can see their latest progress on Facebook. I can't wait until this bad boy is road worthy! :)

Posted in General at Apr 26 2012, 09:46:33 AM MDT Add a Comment

Cruising around the Western Caribbean

I've heard great things about Disney Cruise Lines from friends, especially as a fun adventure for kids. That's why I was super pumped to talk my family into going on a Western Caribbean Cruise for Spring Break. As you might've read in my last post, we spent a week in Crested Butte before embarking on our cruise.

ShotSki Research at The Secret Stash While in Crested Butte, I enjoyed the Java Posse Roundup, but unfortunately had to do client work most of the week. However, that didn't stop James Ward, Trish and me from building a Shot-Ski and doing a 5-minute lightning talk on it. We had a great time doing research, getting locals to help us out and beta testing it with JPR attendees. I'll write a blog post on what we learned in the near future. In the meantime, you can check out Trish's Making a Shot-Ski photos.

We left Crested Butte on Thursday (March 29th) and drove back to Denver to meetup with my parents (who drove down from Montana). Friday morning we hopped on a plane and flew to Orlando, Florida and took a bus to Port Canaveral. Abbie and Jack were at their Grandma's in West Palm Beach, so Trish's parents picked them up on their drive up from Naples. We all met with near perfect timing and boarded the Disney Magic around 4 o'clock Friday afternoon.

Raible's and McGinity's welcome to our Disney Cruise!

The Joes Maureen and Abbie Leaving Port Canaveral First Dinner!

My Dad's Stateroom We were immediately impressed with our rooms (we had 3 staterooms next to each other on the 5th floor forward) and their nice portal windows. We saw dolphins jumping in Port Canaveral as we departed and witnessed a horn battle between our ship and the Disney Fantasy. The Disney Fantasy was embarking on its maiden voyage and we saw it many times throughout the trip. That evening, we ventured to the first dinner seating (at 17:45). We were pleased to find out we'd have the same servers all week, at different restaurants throughout the ship.

Key West
Saturday morning, we arrived in Key West and had from 12am-9pm to explore. We took a tour in Key West and learned a lot about the history and architecture of the town. Last time we visited Key West, I was super impressed with Mel Fisher Maritime Museum. It was fun to show it to everyone and we savored some tasty beverages at Margaritaville afterward.

Abbie on stage in Margaritaville Key West Florida Jimmy Buffet mural at Margaritaville Key West Florida

We returned to the ship for dinner that evening and enjoyed the service of Omar (our main server) and Marijah (his assistant) once again. A couple hours laster, the boys (minus Jack) returned to shore to do some bonding. We wandered about, set a match to some cigars and made it back on the ship before it departed. We spent the remainder of the evening in the ship's Sports Bar watching March Madness and talking about Trish and my upcoming wedding.

Bonding in Key West Key West Memories Bonding Night with the Queen

Sunday was a day at sea and we made the most of it. Lots of swimming, relaxing, playing with kids and enjoying each other's company. The ship had two different places that you could drop your kids off and Abbie (9) had a lot of fun attending their activities. Jack wasn't that into it and spent most of his day visiting the soft-serve ice cream machine. That evening, Trish and I journeyed to a romantic dinner at the ship's 18-and-older restaurant and celebrated our 1-year "moved in together" anniversary.

Grand Cayman
Monday, we arrived at Grand Cayman early in the morning and were ashore by 8am. We had a snorkeling expedition planned so promptly gathered and headed out to sea on a snorkeling boat. The weather was beautiful, the water was warm and snorkeling around a shipwreck was a very memorable experience.

Abbie and Jack arrive in Grand Cayman Islands Baba is excited to go snorkeling!

Barb and Joe going shipwreck snorkeling in Grand Cayman Abbie is a little nervous about the shipwreck

We visited the Hard Rock cafe to get my Dad a t-shirt, purchased some Tobago Rum Cakes and finished with a tour of the new Cayman Islands National Museum. We were back on the ship by 4 so our parents could have their own romantic dinner that evening.

Raible and McGinity dinner

Cozumel
Tuesday morning, we woke up in Cozumel. Trish and my parents headed to shore for some exploring while I slept in with the kids and ate at the "something for everyone" breakfast buffet. In the afternoon, we all headed to shore for a submarine ride. The submarine adventure was very cool, going down 120 ft. and even taking us to the edge of a cliff on the ocean floor. We got to see several schools of fish, loads of coral reef and even a sea turtle swimming along the bottom.

Cute Kids Submariners

Disney Double Date! Mimi and Baba Monkeys

The highlight of Cozumel was Manuel. After the submarine ride, we took a taxi to a restaurant with a great view and had a couple margaritas and some excellent steak tacos. While we were finishing up, a man walked up to us and asked if we wanted him to play us a song on his guitar. We said yes and gave him our small change ($1.75) for his serenade.

Shortly after, we got up to leave the restaurant and walk back to the ship. That's when Trish came up with a brilliant idea and asked Manuel if he'd be willing to walk with us around town and play music the whole time. She offered him $20 and he quickly agreed.

What followed was lots of laughs, smiling and dancing through the streets of Cozumel. Not only from us, but also from many of the locals. Manuel was an excellent mariachi musician and provided an exciting sense of celebration around us for the next 20 minutes.

Trish paid Manuel $20 to walk with us and play... Trish paid Manuel $20 to walk with us and play...

Our posse with our Guitarrón Amigo in the Plaza Cozumel Mexico

Wednesday was another day at sea as we traveled from Cozumel to Disney's private island in the Bahamas: Castaway Cay. We got a kick out of the ship's activities, from Beer Tasting to watching the John Carter movie in 3D. I snapped some sweet photos that night as we were watching the sun set over the horizon.

A thing of beauty

Long Lasting Love

Castaway Cay
At first, I thought Castaway Cay was going to be like Disney World, just on an island. I was expecting all kinds of rides and an amusement park. I was surprised to find it was nothing like that, but more of a private beach with all kinds of bars, games, water sports and even a water slide. The kids had a blast building sand castles, learning how to play checkers and exploring the island. I had a massage to the sound of ocean waves in the afternoon and we hopped back on the ship around 5 that afternoon.

That night, we had to pack up our luggage by 10 and put it out so it could be checked into our flight the next day. Disney did an awesome job of handling our luggage both to and from the cruise. All we had to do was attach bag tags in Denver and our bags arrived at our room shortly after boarding. On the way home, we gave them our bags on Thursday night and didn't see them until arriving in Denver.

Our crew on the Disney Magic!

The last morning on the Disney Magic was a bit early. We had to be at breakfast at 6:45, were off the ship by 8 and at the Orlando airport by 9. Our flight was at 7 that night, so we suddenly found ourselves with 9 hours of free time and nothing to do.

LEGOLAND
Last year around this time, Jack was struggling in school and getting in trouble almost every-other-day. In an attempt to promote good behavior, I told him I'd take him to LEGOLAND if he had 10 days in a row of good behavior. This didn't seem to help and we ended the school year with no trip planned. However, when this school year started, he had excellent behavior (which has continued all year) and quickly remembered my promise.

As we were sitting in Orlando's airport, I remembered this promise and 30 minutes later we had a car rented and were driving to see some legos. We spent a joyous day there, riding the few rides they had and marveling over all the things you could build with legos. It was a fun way to end our wonderful vacation.

This cruise was a first for myself, my kids and my parents. We were extremely impressed with Disney's Customer Service and have never felt more pampered in our lives. All the crew we interacted with knew our names by the second days and were some of the most kid-friendly people I've ever met. The food was excellent, the weather was beautiful and the activities were plentiful. It wasn't until the last night that we realized there were 15 bars on the ship, and by that time it was too late for a pub crawl. Oh well, there's always next time. ;-)

For more pictures from our Disney Magic voyage, see our photos on Flickr.

Posted in General at Apr 15 2012, 06:05:57 PM MDT Add a Comment

Spring Break!

Spring Break is a wonderful time of year. It's near the end of the ski season and spring is in the air. Ever since I split with Abbie and Jack's Mom (5 years ago), she's taken the kids to West Palm Beach (Florida) for Spring Break. Their Grandma is a teacher and she has the time off, so it's always worked out well.

This year, I decided to change things up a bit and plan my own Spring Break vacation. In true "Matt and Trish" style, we didn't just plan a trip to an exotic location for a week, we planned a trip to several exotic locations. We started off by taking the kids to the mountains over the weekend and treating them to a fancy dinner at Devil's Thumb Ranch. This trip was mostly to get our skis for this week's trip.

Office View in Crested Butte Yesterday, we drove back to Denver, dropped the kids off at their Mom's (they're flying to Florida today) and continued on to Crested Butte (a.k.a. "the last great Colorado ski town"). In Crested Butte, I'm signed up for the Java Posse Roundup. We're here for the week to enjoy the conference, the beautiful weather and the great town of Crested Butte. I'm sure we'll figure out a way to get some Spring Skiing in along the way. We're staying at The Ruby of Crested Butte, which turns out to be the nicest Bed & Breakfast I've ever stayed in (thanks for the recommendation James!).

This Friday, we'll be heading to another adventure with the kids and both Trish and my parents. I'll make sure and write about our journey when we return. In the meantime, I've discovered the kids only have 1 week off for spring break, not 2 weeks. So I guess I'm to blame for them playing hookie on a boat when they should be in school. Oh well, they don't look too upset, do they? :)

Abbie and Jack

Posted in General at Mar 26 2012, 10:01:44 AM MDT Add a Comment

A Spectacular Trip to Stockholm and Madrid

When I travel in the winter, it's usually to ski resorts or client sites, not to conferences. However, when the Mattias Karlsson invited me to speak at Jfokus, I jumped at the opportunity. That same day in Antwerp, Sergi Almar asked me to speak at Spring I/O. Turns out, both conferences were in the same week so we worked out the logistics of traveling to Stockholm and Madrid and got ready for a spectacular trip.

Trish and I started our journey two weeks ago by flying over the top of world, connecting through Seattle and Reykjavik (Iceland) before arriving in Stockholm on Monday afternoon. We took the bullet train from the airport to downtown and walked a couple blocks to the conference venue/hotel. We checked in, relaxed, then met a bunch of folks a few hours later to go to the speaker's dinner at F12.

James Ward and Enno Runne by Trish McGinity Juergen Hoeller Speakers Dinner Singers Matt Raible James Ward Rickard Oberg Jfokus speakers dinner

On Tuesday, I attended quite a few sessions at the conference, took and nap and delivered my Comparing JVM Web Frameworks talk at 17:00. The Atlassian Bar opened after my talk concluded and we enjoyed some tasty beverages while talking tech with new and old friends. James Ward's Cloud BOF started at 8 and we enjoyed the beer and banter before heading out to the local Sports Bar. We scared the bar's proprietors with our hunger and thirst at such a late hour, but they served us anyway.

John Wilander Jfokus 2012 Thanks for the beer Atlassian! Cloud Conversations Heroku James Ward After BOF Dinner Crew

On Wednesday, I got woken up by the hotel's housekeeping at 9:52 and I had to be on stage at 10:10. I got dressed and downstairs as fast as I could and put the final touches on my presentation as people were filing in the room. I opened my talk with, "You ever had one of those morning where the housekeeping woke you up and you had to be on stage 10 minutes later?"

The conference ended that day, but Trish and I extended it a bit by going to the Scala Stockholm Meetup and walking around the city to capture some night photos. I wrote up a blog post about my presentations and Jfokus the next morning and Trish posted both her Jfokus and Stockholm pictures to Flickr. Below are some of my favorite pictures of Sweden.

Stockholm bike along rail

Storkyrkan Saint Nicolaus Church Stockholm Stockholm Town Hall
Stockholm Evening
Stockholm Lion
Riddenholm Church
Stockholm View

On Thursday, we traveled to Madrid for Spring I/O. We arrived at sunset and met up with Josh Long and his Dad for a ride to our hotel. Trish went to high school in Puerto Rico and got to show of her Spanish skills when she helped the driver find the hotel. I spoke on Friday morning and we spent the rest of the weekend taking photos and enjoying Carnival. We had a great hotel in the heart of Madrid and could walk to almost all the historic sites.

It was great seeing Trish in Madrid. Her Spanish was excellent and I felt like I had a personal tour guide the whole time. Her pictures show the weather was beautiful and the sites, amazing.

Templo de Debod

Iglesia San Gines Palace Real

Plaza Mayor Madrid Evening Commute Puerta de Alcala Madrid

Almudena Cathedral

You can see all of Trish's Madrid photos on Flickr. I also published mine in a Stockholm and Madrid 2012 album.

Yes, it was quite a bit of work preparing for two conferences in one week. However, both were in exotic, beautiful locations. Not only that, but Mattias and Sergi did a great job of providing terrific local experiences. Thanks guys, we had a blast.

Happy Travelers in Madrid

For more of Trish's photos from our world travels, see McGinity Photo's World Gallery.

Posted in General at Feb 26 2012, 09:11:03 PM MST 2 Comments

Comparing Web Frameworks and HTML5 with Play Scala at Jfokus 2012

Riddenholm Church Stockholm seems a lot like Denver this time of year. Cold, snowy and beautiful. Trish and I arrived in Stockholm (Sweden) on Monday for the Jfokus conference and we're traveling to Madrid today for the Spring I/O conference. I was invited to Jfokus within minutes of delivering my HTML5 with Play Scala talk at Devoxx.

Both the Jfokus and Spring I/O Organizers were interested in my Comparing JVM Web Frameworks talk, so I updated it to reflect my latest thoughts. First of all, I mentioned that there's a lot of great frameworks out there and I think the reason people are so apprehensive to choose one is because they've chosen badly at one point. This might've been Struts back in the day (even thought it was one of the best frameworks at the time) or it might be because a vendor talked them into it. However, if you look at the modern JVM frameworks today, you should be able to see that they're all pretty awesome.

I mentioned how I think Web developers should know JavaScript and CSS. If you're a Java developer and you call yourself a web developer, you're letting your framework do too much of the work for you. I mentioned Rich Manalang's Modern Principles in Web Development, where he talks about his core web development principles.

  • Designing for mobile first (even if you’re not building a mobile app)
  • Build only single page apps
  • Create and use your own REST API
  • “Sex sells” applies to web apps

I've found these principles to be true in my own experience and suggested that if you want to be a web developer, the frameworks you might want to learn are not traditional JVM web frameworks, but rather client-side MVC frameworks. For those Java developers that don't want to be web developers, I suggest they strengthen their services development knowledge by reading Hot to GET a Cup of Coffee.

You can see my updated presentation below, on Slideshare or as a downloadable PDF. You can also watch the video.

I delivered my 2nd presentation on HTML5 with Play Scala, CoffeeScript and Jade on Wednesday morning. This talk is one of my favorites and I prepared for it over the last several weeks by adding JSON CRUD Services and SecureSocial to my HTML5 Fitness Tracking application. Right before we left for Jfokus, I was able to get everything to work, but didn't spend as much time as I'd like working on the mobile client. If this talk gets accepted for Devoxx France, I plan on spending most of my time enhancing the mobile client. After my latest experience developing, I can see how Rich's first principle (above) makes a lot of sense.

Below is my presentation for this talk. Of course, it's on Slideshare and downloadable as a PDF.

I also updated the Developing Play More demo video to show my latest efforts.

Delivering these talks at Jfokus was a lot of fun. Yes, it was a lot of work and stress to prepare them. However, I also learned a lot creating them and I hope the audience benefitted from that.

Jfokus 2012 The conference itself was incredible. I got to meet Peter Hilton and Helena Hjertén as I was registering. The speaker's dinner at F12 was off-the-hook good and I had the pleasure of finally meeting Rickard Öberg.

I also attended some fantastic presentations, including Peter Hilton's Play Framework 2.0, Bodil Stokke's CoffeeScript: JavaScript without the Fail, Pamela Fox's Client-side Storage and Heiko Seeberger's Scala in Action. I don't know if Heiko has published any slides, but I'm guessing not since most of his presentation was live coding.

I have lots of good memories from Jfokus. Many thanks to Mattias for inviting me!

Posted in Java at Feb 16 2012, 12:01:05 AM MST 5 Comments

Play Framework 2.0 with Peter Hilton at Jfokus

This week, I'm at Jfokus in Stockholm, Sweden. After a fun speaker's dinner last night, I got up this morning and polished up my presentations and demo before attending the conference. The first session I attended was Peter Hilton's Play Framework 2.0 presentation. Below are my notes from this talk.

Peter is a Senior Web Developer, not a Java Developer. His first slide states the following:

"Play brings type safe high-productivity web development to the JVM."

New features in Play 2.0: type-safety, template syntax, compile-time checking and asynchronous HTTP programming. Java, Scala - the language you use is less important than the fact that Play is a web framework. It's a full-stack framework and has everything you need out-of-the-box to build a web application. Play focuses on HTTP and doesn't try to hide it. It's designed by web developers for web developers.

With Play, the Back button just works. Your web framework shouldn't break the first button on your browser's toolbar. The Reload button also works: make a change, hit reload and your changes (even in Scala classes) are shown. You design the URLs and you can use "clean" URLs. DX (Developer eXperience) is Peter's new term. Usability matters: as a developer, you deserve a framework that provides a good experience.

Play doesn't fight HTTP or the browser. It's stateless and HTTP-centric. A few years ago, it seemed like a good idea to try and keep state on the server. It sounded like a good idea, but in practice, it's a really bad idea - especially for things like the back button. Play matches the web's stateless HTTP architecture.

As a Java EE developer, PHP and Rails developers have been laughing at us for years. Like Father Christmas, Peter's heard of class-reloading, but he hasn't actually seen it. Code reloading is the most important part of DX and about achieving high-productivity in web development.

URLs want to be loved too. REST architecture isn't just for web service APIs. When you have clean URLs, you can tweet them, post them and email them.

"You would need to be a super-hero to successfully use some web frameworks." They show you a blank screen in the browser and you have to look at your console's stack trace to figure it out. With Play, the error is shown in your browser and you can see the exact line it happens on.

In Play 1.x, there was a lot of magic and a lot of bytecode enhancement at runtime. This allowed the API to be a lot nicer than traditional Java APIs. However, it caused issues when users viewed the enhanced source and it also caused issues in IDEs. With Play 2.0, the framework itself is implemented in Scala. Scala removes the need for so much bytecode enhancement. There is less 'magic' and strangeness in the API. The code you see in the IDE is the code that runs. Scala source code is not necessarily harder to read. 1.x had some pretty hairy Java code, and you could tell when you dug into it. Especially when you were deep into the source code and saw that a lot of the comments were in French.

Play 2.0's template system is based on Scala. It's similar to the lightweight template syntax in Play 1.x. Templates are compiled into class files for run-time speed. For example:

@(products: Seq[Product])

<ul>
@for(product <- products) {
  <li>@product.name</li>
}
</ul>

@summary(products)

We used to think XML-based templates were great, but it turns out it's a terrible idea. Mostly because you end up having to invent an expression language to create valid XML (to avoid putting XML in your HTML attributes). With Play 2.0's templates, you can define tags in your templates as regular Scala methods.

@display(product: models.Product) ={
 <a href="@routes.Product.details(product.id)">@product.name</a> 
}

@for(product <- products) {
  @display(product)
}

The compile-time checking in Play 2.0 is not just for Java and Scala classes. It also compiles your HTTP routes file (which maps requests to controller actions). Furthermore, it compiles your templates, JavaScript files (using Google Closure Compiler), CoffeeScript files and LESS stylesheets.

Play supports modern web development. It's designed to work with HTML5, but there's no constraints on HTML output. It's front-end developer friendly and has great DX. UI components belong in the client, e.g. jQuery UI. It also has built-in support for improvements to CSS (LESS) and JavaScript (CoffeeScript).

A few years ago, it seemed like a really good idea to hide JavaScript from the web developer. Web frameworks used to say "You don't need to see the JavaScript or the HTML, we'll handle generating your components for you." Now, if you're building a web application and you don't know any jQuery, you doing it the hard way. You should learn how to work with front-end developers or learn how to do it yourself. And make sure your web framework allows this sort of development.

The future of web programming is asynchronous. You'll perform simultaneous web service requests. You'll process streams of data, instead of filling up memory or disk. You'll publish real-time data and have predictable and minimal resource consumption. In the long term, this changes everything. The future of the web is real-time and asynchronous. With Play 2.0, it's not just another feature, it's a fundamental aspect of the architecture. Play's internal architecture uses a reactive model based on Iteratee IO.

In summary, use Play 2, use HTML5, deploy to the Cloud. There's two forthcoming books on Play (both from Manning) and Play 2.0 RC1 will be released today.

I think Peter did a good job of summarizing the new features in Play 2.0, especially how templates work. I enjoyed his emphasis on HTTP and how Play leverages the browser (back, reload and as a console). I liked his humorous speaking style, and agree with his emphasis that client-side development skills are important for modern web applications. I think Play 2.0 is making a big bet on Scala and asynchronous programming, but if they live up to the hype, it should be a very enjoyable web framework to develop with.

Posted in Java at Feb 14 2012, 07:17:08 AM MST 2 Comments

Secure JSON Services with Play Scala and SecureSocial

AntwerpTownSquare Last November, I traveled to Antwerp to speak at Devoxx. After my talk on HTML5 with Play Scala, Mattias Karlsson approached me and we had a chat about doing the same talk at Jfokus in Stockholm. I agreed and we began talking details after Trish and I returned to the US.

Jfokus

I wrote this article on a plane between Denver and Seattle and will be hopping over the North Pole to Stockholm via Iceland tonight. For the past couple of weeks, I've been updating my Play More! HTML5/mobile app to add some new features. Most notably, I wanted to upgrade to Play 2.0, create JSON services and add authentication.

Upgrading to Play 2.0
My attempt to upgrade to Play 2.0 involved checking out the source from GitHub, building and installing the RC1 snapshot. As I tried to upgrade my app and started getting failed imports, I turned to the internet (specifically StackOverflow) to see if it was a good idea. The first answer for that question suggested I stay with 1.x.

If it's a critical project, to be finished before next March 2012, I would go with Play 1.x. If it's a less important project, which could be delayed, and that in any case won't be released before March 2012, try Play 2.0.

While I didn't plan on releasing Play More! before Jfokus, I decided upgrading didn't add a whole lot to the talk. Also, I couldn't find a Play Scala 0.9.1 to Play 2.0 upgrade guide and I didn't have enough time to create one. So I decided to stick with Play 1.2.4 and add some JSON services for my iPhone client.

JSON Servers
I found Manuel Bernhardt's Play! Scala and JSON. This led me to Jerkson, built by the now infamous @coda. I was able to easily get things working fairly quickly and wrote the following WorkoutService.scala:

package controllers.api

import play.mvc.Controller
import models._
import com.codahale.jerkson.Json._

object WorkoutService extends Controller {

  def workouts = {
    response.setContentTypeIfNotSet("application/json")
    generate(Workout.find().list())
  }
  def edit(id: Long) = {
    generate(Workout.byIdWithAthleteAndComments(id))
  }

  def create() = {
    var workout = params.get("workout", classOf[Workout])
    Workout.create(workout)
  }

  def save(id: Option[Long]) = {
    var workout = params.get("workout", classOf[Workout])
    Workout.update(workout)
  }

  def delete(id: Long) = {
    Workout.delete("id={id}").on("id" -> id).executeUpdate()
  }
}

Next, I added routes for my new API to conf/routes:

GET     /api/workouts               api.WorkoutService.workouts
GET     /api/workout/{id}           api.WorkoutService.edit
POST    /api/workout                api.WorkoutService.create
PUT     /api/workout/{id}           api.WorkoutService.save
DELETE  /api/workout/{id}           api.WorkoutService.delete

Then I created an ApiTest.scala class that verifies the first method works as expected.

import play.test.FunctionalTest
import play.test.FunctionalTest._
import org.junit._

class ApiTests extends FunctionalTest {
  
    @Test
    def testGetWorkouts() {
        var response = GET("/api/workouts");
        assertStatus(200, response);
        assertContentType("application/json", response)
        println(response.out)
    }
}

I ran "play test", opened my browser to http://localhost:9000/@tests and clicked ApiTests -> Start to verify it worked. All the green made me happy.

Play More API Tests

Finally, I wrote some CoffeeScript and jQuery to allow users to delete workouts and make sure delete functionality worked.

$('#delete').click ->
  $.ajax
    type: 'POST'
    url: $(this).attr('rel')
    error: ->
      alert('Delete failed, please try again.')
    success: (data) ->
      location.href = "/more"

I was very impressed with how easy Play made it to create JSON services and I smiled as my CoffeeScript skills got a refresher.

The Friday before we left for Devoxx, I saw the module registration request for SecureSocial.

SecureSocial with Play Scala
From SecureSocial's README:

SecureSocial allows you to add an authentication UI to your app that works with services based on OAuth1, OAuth2, OpenID and OpenID+OAuth hybrid protocols.

It also provides a Username and Password mechanism for users that do not wish to use existing accounts in other networks.

The following services are supported in this release:

  • Twitter (OAuth1)
  • Facebook (OAuth2)
  • Google (OpenID + OAuth Hybrid)
  • Yahoo (OpenID + OAuth Hybrid)
  • LinkedIn (OAuth1)
  • Foursquare (OAuth2)
  • MyOpenID (OpenID)
  • Wordpress (OpenID)
  • Username and Password

In other words, it sounded like a dream come true and I resolved to try it once I found the time. That time found me last Monday evening and I sent a direct message to @jaliss (the module's author) via Twitter.

Does Secure Social work with Play Scala? I'd like to use it in my Play More! project.

Jorge responded 16 minutes later saying that he hadn't used Play Scala and he'd need to do some research. At 8 o'clock that night (1.5 hours after my original DM), Jorge had a sample working and emailed it to me. 10 minutes later I was adding a Secure trait to my project.

package controllers

import play.mvc._
import controllers.securesocial.SecureSocial

/*
 * @author Jorge Aliss <[email protected]> of Secure Social fame.
 */
trait Secure {
  self: Controller =>

  @Before def checkAccess() {
    SecureSocial.DeadboltHelper.beforeRoleCheck()
  }

  def currentUser = {
    SecureSocial.getCurrentUser
  }
}

I configured Twitter and Username + Password as my providers by adding the following to conf/application.conf.

securesocial.providers=twitter,userpass

I also had to configure a number of securesocial.twitter.* properties. Next, I made sure my routes were aware of SecureSocial by adding the following to the top of conf/routes:

  *       /auth               module:securesocial

Then I specified it as a dependency in conf/dependencies.yml and ran "play deps".

    - play -> securesocial 0.2.4

After adding "with Secure" to my Profile.scala controller, I tried to access its route and was prompted to login. Right off the bat, I was shown an error about a missing jQuery 1.5.2 file in my "javascripts" folder, so I added it and rejoiced when I was presented with a login screen. I had to add the app on Twitter to use its OAuth servers, but I was pumped when both username/password authentication worked (complete with signup!) as well as Twitter.

The only issue I ran into with SecureSocial was that it didn't find the default implementation of SecureSocial's UserService.Service when running in prod mode. I was able to workaround this by adding a SecureService.scala implementation to my project and coding it to talk to my Athlete model. I didn't bother to hook in creating a new user when they logged in from Twitter, but that's something I'll want to do in the future. I was also pleased to find out customizing SecureSocial's views was a breeze. I simply copied them from the module into my app's views and voila!

package services

import play.db.anorm.NotAssigned
import play.libs.Codec
import collection.mutable.{SynchronizedMap, HashMap}
import models.Athlete
import securesocial.provider.{ProviderType, UserService, SocialUser, UserId}

class SecureService extends UserService.Service {
  val activations = new HashMap[String, SocialUser] with SynchronizedMap[String, SocialUser]

  def find(userId: UserId): SocialUser = {
    val user = Athlete.find("email={email}").on("email" -> userId.id).first()

    user match {
      case Some(user) => {
        val socialUser = new SocialUser
        socialUser.id = userId
        socialUser.displayName = user.firstName
        socialUser.email = user.email
        socialUser.isEmailVerified = true
        socialUser.password = user.password
        socialUser
      }
      case None => {
        if (!userId.provider.eq(ProviderType.userpass)) {
          var socialUser = new SocialUser
          socialUser.id = userId
          socialUser
        } else {
          null
        }
      }
    }
  }

  def save(user: SocialUser) {
    if (find(user.id) == null) {
      val firstName = user.displayName
      val lastName = user.displayName
      Athlete.create(Athlete(NotAssigned, user.email, user.password, firstName, lastName))
    }
  }

  def createActivation(user: SocialUser): String = {
    val uuid: String = Codec.UUID()
    activations.put(uuid, user)
    uuid
  }

  def activate(uuid: String): Boolean = {
    val user: SocialUser = activations.get(uuid).asInstanceOf[SocialUser]
    var result = false

    if (user != null) {
      user.isEmailVerified = true
      save(user)
      activations.remove(uuid)
      result = true
    }

    result
  }

  def deletePendingActivations() {
    activations.clear()
  }
}

Jorge was a great help in getting my authentication needs met and he even wrote a BasicAuth.scala trait to implement Basic Authentication on my JSON services.

package controllers

import _root_.securesocial.provider.{UserService, ProviderType, UserId}
import play._
import play.mvc._
import play.libs.Crypto

import controllers.securesocial.SecureSocial

/*
 * @author Jorge Aliss <[email protected]> of Secure Social fame.
 */
trait BasicAuth {
  self: Controller =>

  @Before def checkAccess = {
    if (currentUser != null) {
      // this allows SecureSocial.getCurrentUser() to work.
      renderArgs.put("user", currentUser)
      Continue
    }

    val realm =
      Play.configuration.getProperty("securesocial.basicAuth.realm", "Unauthorized")

    if (request.user == null || request.password == null) {
      Unauthorized(realm)
    } else {
      val userId = new UserId
      userId.id = request.user
      userId.provider = ProviderType.userpass
      val user = UserService.find(userId)

      if (user == null ||
        !Crypto.passwordHash(request.password).equals(user.password)) {
        Unauthorized(realm)
      } else {
        // this allows SecureSocial.getCurrentUser() to work.
        renderArgs.put("user", user)
        Continue
      }
    }
  }

  def currentUser = {
    SecureSocial.getCurrentUser()
  }
}

Summary
My latest pass at developing with Scala and leveraging Play to build my app was a lot of fun. While there were issues with class reloading every-so-often and Scala versions with Scalate, I was able to add the features I wanted. I wasn't able to upgrade to Play 2.0, but I didn't try that hard and figured it's best to wait until its upgrade guide has been published.

I'm excited to describe my latest experience to the developers at Jfokus this week. In addition, the conference has talks on Play 2.0, CoffeeScript, HTML5, Scala and Scalate. I hope to attend many of these and learn some new tricks to improve my skills and my app.

Update: The Delving developers have written an article on Migration to Play 2. While it doesn't provide specific details on what they needed to change, it does have good information on how long it took and things to watch for.

Posted in Java at Feb 12 2012, 04:02:43 PM MST 4 Comments

My What's New in Spring 3.1 Presentation

My first business trip of the year was to Dublin, CA this past week. Trish joined me because she wanted to take some pictures of San Francisco. She got some awesome shots as you can see below.

Lombard Ave in SF with Bay view Kissing Sea lions Pier 38 San Fran San Francisco Bay Bridge at Night Bay Bridge San Francisco at Night

Balclutha Maritime Museum San Fran

On Tuesday night, I attended Twitter's Open Source Summit with a co-worker and had a great time.

On Wednesday, I talked about What's New in Spring 3.1 at the Silicon Valley Spring User Group. I discussed the support for Java 7, Servlet 3, Hibernate 4 (and JPA 2 with Spring Data) and the new Cache Abstraction. I mentioned how spring-data-jpa-examples is a great sample project and showed a bunch of code from my Spring Kickstart project. I was surprised to find that no one in the audience (all Spring users) was using Java Config. Below are the slides from my presentation and you can also download the PDF.

Posted in Java at Feb 04 2012, 05:47:14 PM MST 2 Comments

Twitter's Open Source Summit: Bootstrap 2.0 Edition

Every few months, Twitter hosts an Open Source Summit to talk about tools they're using. Since I happened to be near San Fransisco, I happily attended their latest #ossummit to learn about Bootstrap 2.0. Below are my notes from last night's event.

95% of Twitter's infrastructure is powered by open source. They hope to contributing back to open source by doing 2-3 summits per year. Without open source, there would be no Twitter. You can find a bunch of Twitter's open source contributions at twitter.github.com. They're also big fans of Apache and commit to a wide variety of projects there.

Bootstrap
Bootstrap is developed by two main guys: @mdo and @fat. Mark (@mdo) has been a designer at Twitter for 2 years. He started on the Revenue Team with ads, but has been working on redesign for last 4 months. Has been doing HTML and CSS for about 11 years. He used Notepad on Windows to build his GeoCities site.

boot·strap: simple and flexible HTML, CSS, and JavaScript for popular user interface components and interactions.

Work on Bootstrap started about a 1.5 years ago. Internal tools didn't get the proper attention they needed. They figured out there was a lot of people that wanted good looking UIs and interactions. It became Twitter Blueprint and was mostly used internally. Jacob (@fat) started shortly after first release and decided to add some JavaScript on top of it. The JavaScript for Bootstrap was originally the "Twitter Internal Toolkit" or "TIT" and was built on Moo Tools. Jacob was like "we gotta open source this, it's gonna be huge!" (he was right).

The 1.0 release supported Chrome, Safari and Firefox (everyone at Twitter was on Macs). 1.3 added cross-browser support and JavaScript plugins.

Now there's Bootstrap 2 (just released!). They rewrote all the documentation and components and removed legacy code.

So, what's new? The biggest thing is the docs. Previously had live examples, now shows live examples and why you would do something, as well as additional options. The "topbar" has been renamed to "navbar", but it's still got all the hotness. It's responsive with CSS media queries for small devices, tablets, small desktops and large desktops. This means the layout breaks at certain points and stacks elements to fit on smaller screens.

CSS: smarter defaults, better classes. In 1.4, all forms were stacked. Now they can flow horizontally. Tables are now namespaced so Bootstrap's styles don't apply to all tables. The available table, form and navigation classes are as follows:

// Tables
.table { ... }
.table-striped { ... }
.table-bordered { ... }
.table-condensed { ... }

// Forms
.form-inline { ... }
.form-search { ... }
.form-horizontal { ... }

// Nav
.nav { ... }
.nav-tabs { ... }
.nav-pills { ... }

The goals with 2.0 are consistency, simplification and future-proofing styles. With 1.4, buttons used "btn primary" and it caused problems if you wanted to have a "primary" class in your project. With 2.0, buttons and all elements are namespaced to avoid collisions (now it's .btn-primary).

After Mark finished talking about the design of Bootstrap, Jacob (@fat) started talking about Bootstrap's JavaScript. Jacob works on The Platform Team at Twitter and claims he made a lot of mistakes with 1.x. However, thanks to semantic versioning, 2.0 is a new version and he got to start over!

The biggest change in 2.0 is the use of data attributes (a.k.a. data-*). They were using them in 1.x, but not to the full potential of what they can be and should be. The first class API for Bootstrap JavaScript is data attributes (or HTML), not JavaScript.

With 1.x, you could add an anchor to close modals and alerts.

// 1.x closing modal/alerts
<a class="close" href="#">×</a>

However, if you put your alerts in your modals, you close them all when you likely only wanted to close one. 2.0 uses a "data-dismiss" attribute.

<a class="close" data-dismiss="model">×</a>

This allows you to target what you want closed (modals or alerts, etc.). You know exactly what's going to happen just by reading the code. Another example is the "href" attribute of an anchor. Rather than using "href", you can now use "data-target".

// 1.x href = target
<a href="#myModal" data-toggle="modal">Launch</a>

// 2.x data-target = target
<a data-target=".fat" data-toggle="modal">Launch</a>

If you'd rather turn off the data attribute API, or just part of it, you can do so by using the following:

// Turn off all data-api
$('body').off('.data-api')

// Turn off alert data-api
$('body).off('.alert.data-api')

2.0's JavaScript API has the same stuff, but better. You can turn off the data-api and do everything with JavaScript. They copied jQuery UI in a lot of ways (defaults, constructors, etc.). Bootstrap's JavaScript has 12 plugins. New ones include collapse, carousel and typeahead.

Customize - a new tab that lets you customize and download Bootstrap. It's basically an alternative to customizing .less files and allows you to choose components, select jQuery plugins, customize variables (colors, font-sizes, backgrounds) and download.

What does the future hold? Internationalization, improving responsiveness, more new features and bug fixes.

After both Mark and Jacob gave their talks, they talked together about Community and how great it's been. Even if you're not into writing CSS and JavaScript, they mentioned they still wanted to hear from you. To give an example of great community contributions, one guy opened 50 issues in the last 2 days.

Someone in the audience asked why they used LESS over SASS. Jacob said the main reason they use LESS is because they're good friends with the guy who invented it (Alexis). SASS turns CSS into a programming language, but they wanted to maintain the approachability of CSS, which LESS does. There's no plans to do an official SASS port, but there is talk of doing one. One advantage of the current LESS compiler is they rewrote it to have better output so it's far more readable.

NASA
After Mark and Jacob finished, there was a 5 minute break to grab beers and snacks. Then Sean Herron (@seanherron) (a.k.a. "NASA Bro") talked about Bootstrap at NASA. He actually didn't talk about Bootstrap much, except that they used it for code.NASA. He talked about NASA and how it's playing a key role in the movement towards open data, open source and open standards in our federal government. He mentioned how data.NASA was launched last August and that they helped develop OpenStack. Finally, he mentioned open.NASA, which is a collaborative approach to open, direct and transparent communication about our space program.

Hogan.js
Next up, Rob Sayre (@sayrer) talked about Hogan.js. Rob has been at Twitter for a few months, before that he wrote JavaScript at other places. Hogan.js is a compiler for Mustache templates.

Why Mustache? Because it's similar to HTML and easy to edit. You can mock data as JSON files and programmers are not required.

At Twitter, designers can do the CSS and Mustache without connecting to the backend. It has cross-language support in Ruby, Java and JavaScript. However, client-side template compilation has performance problems, especially in IE7 on a Windows XP box with 4 viruses.

So they had a few choices: work on mustache.js, or use Dust.js or Handlebars.js. The compilers are very nice for Dust.js and Handlebars.js, but they're huge. Handlebar's parser is 4000 lines. The entire Hogan.js file is 500 lines. They decided they were too large to send to the browser's of their users, so they chose to write a better compiler for Mustache.

Hogan.js's main features:

  • Compile on the server
  • Parser API
  • Performance

Performance is much better with Hogan.js than Mustache.js. On IE7 - Hogan is 5x faster than Mustache. On an iPhone, it's about the same (and an iPhone's browser is faster than IE7 on a decent computer). With modern browsers (Chrome 17, Safari 5 and Firefox 10), it's more than 10x faster.

Hogan.js is currently used at Twitter for Tweet embedding, the Bootstrap build process and soon, Twitter.com.

It's been awhile since I got excited about an open source project. Bootstrap has helped me a lot recently, in my Play More! mobile app, on some client projects and I'm in the process of refreshing AppFuse's UI to use it. I love how you can add a class or two to an element and all of a sudden they pop with good looks. The main problem with Bootstrap at this point is that a lot of Bootstrapped apps look the same. There's talk of adding themes in a future release to help alleviate this problem. In the meantime, there's a lot to get excited about with 2.0.

Thanks to Twitter for hosting this event and kudos to Mark and Jacob (and the community!) for such a fantastic project.

Posted in The Web at Feb 01 2012, 11:28:40 AM MST Add a Comment

Refreshing AppFuse's UI with Twitter Bootstrap

The last time AppFuse had an update done to its look and feel was in way back in 2006. I've done a lot of consulting since then, which has included a fair bit of page speed optimization, HTML5 development and integrating smarter CSS. It was way back in '05 when we first started looking at adding a CSS Framework to AppFuse. It was Mike Stenhouse's CSS Framework that provided the inspiration and my CSS Framework Design Contest that provided its current themes (puzzlewithstyle, andreas01 and simplicity).

Since then, a lot of CSS Frameworks have been invented, including Blueprint in 2007 and Compass in 2008. However, neither has taken the world by storm like Twitter Bootstrap. From Building Twitter Bootstrap:

A year-and-a-half ago, a small group of Twitter employees set out to improve our team’s internal analytical and administrative tools. After some early meetings around this one product, we set out with a higher ambition to create a toolkit for anyone to use within Twitter, and beyond. Thus, we set out to build a system that would help folks like us build new projects on top of it, and Bootstrap was conceived.
...
Today, it has grown to include dozens of components and has become the most popular project on GitHub with more than 13,000 watchers and 2,000 forks.

The fact that Bootstrap has become the most popular project on GitHub says a lot. For AppFuse.next, I'd like to integrate a lot of my learnings over the past few years, as well as support HTML5 and modern browsers as best we can. This means page speed optimizations, getting rid of Prototype and Scriptaculous in favor of jQuery, adding wro4j for resource optimization and integrating HTML5 Boilerplate. I've used Twitter Bootstrap for my Play More! app, as well as some recent client projects. Its excellent documentation has made it easy to use and I love the way you can simply add classes to elements to make them transform into something beautiful.

Last week, I spent a couple late nights integrating Twitter Bootstrap 2.0 into the Struts 2 and Spring MVC versions of AppFuse. The layout was pretty straightforward thanks to Scaffolding. Creating the Struts Menu Velocity template to produce dropdowns wasn't too difficult. I added class="table table-condensed" to the list screen tables, class="well form-horizontal" to forms and class="btn primary" to buttons.

I also added validation errors with the "help-inline" class. This is also where things got tricky with Struts and Spring MVC. For the form elements in Bootstrap, they recommend you use a "control-group" element that contains your label and a "controls" element. The control contains the input/select/textarea and also the error message if there is one. Here's a sample element waiting for data:

<div class="control-group">
    <label for="name" class="control-label">Name</label>
    <div class="controls">
        <input type="text" id="name" name="name">
    </div>
</div>

Below is what that element should look like to display a validation error:

<div class="control-group error">
    <label for="name" class="control-label">Name</label>
    <div class="controls">
        <input type="text" id="name" name="name" value="">
        <span class="help-inline">Please enter your name.</span>
    </div>
</div>

You can see this markup is pretty easy, you just need to add an "error" class to control-group and span to show the error message. With Struts 2, this was pretty easy thanks to its customizable templates for its tags. All I had to do was create a "template/css_xhtml" directory in src/main/webapp and modify checkbox.ftl, controlfooter.ftl, controlheader-core.ftl and controlheader.ftl to match Bootstrap's conventions.

Spring MVC was a bit trickier. Since its tags don't have the concept of writing an entire control (label and field), I had to do a bit of finagling to get things to work. In the current implementation, Struts 2 forms have a single line for a control-group and its control-label and controls.

<s:textfield key="user.firstName" required="true"/>

With Spring MVC, it's a bit more complex:

<spring:bind path="user.firstName">
<fieldset class="control-group${(not empty status.errorMessage) ? ' error' : ''}">
</spring:bind>
    <appfuse:label styleClass="control-label" key="user.firstName"/>
    <div class="controls">
        <form:input path="firstName" id="firstName" maxlength="50"/>
        <form:errors path="firstName" cssClass="help-inline"/>
    </div>
</fieldset>

You could probably overcome this verbosity with Tag Files.

Figuring out if a control-group needed an error class before the input tag was rendered was probably the hardest part of this exercise. This was mostly due to Bootstrap's great documentation and useful examples (viewed by inspecting the markup). Below are some screenshots of the old screens and new ones.

Old UI - Login Old UI - Users Old UI - Edit Profile

New UI - Login New UI - Users New UI - Edit Profile

Check out the full set on Flickr if you'd like a closer look.

Even though I like the look of the old UI, I can't help but think a lot of the themes are designed for blogs and content sites, not webapps. The old Wufoo forms were a lot better looking though. And if you're going to develop kick-ass webapps, you need to make them look good. Bootstrap goes a long way in doing this, but it certainly doesn't replace a good UX Designer. Bootstap simply helps you get into HTML5-land, start using CSS3 and it takes the pain out of making things work cross-browser. Its fluid layouts and responsive web design seems to work great for business applications, which I'm guessing AppFuse is used for the most.

I can't thank the Bootstrap developers enough for helping me make this all look good. With Bootstrap 2 dropping this week, I can see myself using this more and more on projects. In the near future, I'll be helping integrate Bootstrap into AppFuse's Tapestry 5 and JSF versions.

What do you think of this CSS change? Do you change your CSS and layout a fair bit when starting with AppFuse archetypes? What can we do to make AppFuse apps look better out-of-the-box?

Update: I updated AppFuse to the final Bootstrap 2.0 release. Also, Johannes Geppert wrote a Struts 2 Bootstrap Plugin. I hope to integrate this into AppFuse in the near future.

Posted in Java at Jan 31 2012, 05:12:17 PM MST 10 Comments