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.

How We Hired a Team of 10 in 2 Months

Back in December, I started a new contract with Time Warner Cable (TWC). As part of the terms of that contract, it named the following as one of my deliverables:

Assist in identifying, recruiting and hiring additional full-time Web development staff, emphasizing open-source framework expertise.
    - Timeframe: ongoing, throughout the six-month engagement
    - Deliverable: targeting 2-3 quality leads/hires

Since this was a local gig and I always like a good challenge, I asked my client to raise the number from 2-3 to 4-5. Shortly after signing that contract, my project began. Almost immediately, I began spreading the word on Twitter.

When TWC hired me, it was just the beginning of a larger initiative. They were making a number of large changes:

  • Moving from Waterfall to Agile.
  • Restructuring organizationally for functional teams.
  • Moving from ColdFusion to JVM technologies.

To help with the move to Agile, I contacted a good friend, Brad Swanson. Brad is the founder of Propero Solutions and has always had a passion for agile coaching and making teams more efficient. At the beginning of the year, we setup 2-day training class in Herndon, VA to kick-off the Agile Initiative. There were 15 existing developers on the team when I started and 40 people showed up to that initial training. Most of these additional folks were from Product and QA. Brad's message of working together quickly resonated with the group and you could see their eyes light up with their new-found knowledge.

After the success of Brad's training, we leveraged his network to help us find some very impressive coaches to assist with our efforts. We hired two Agile Coaches to start working with us at the end of January.

While our agile movement was progressing in January, I started contacting friends, former colleagues and referrals about coming to work for us. For friends and former colleagues, my e-mail simply outlined the positions available, the exciting opportunity of the project and that TWC was willing to pay very competitive salaries for strong engineers. While it didn't happen immediately, I did manage to convince 4 former co-workers to join me, including the team I built at LinkedIn and worked with at Evite.

Following those 4, most of the candidates we interviewed were referrals or folks that contacted me directly after seeing my tweet. I'm amazed that I never had to write a blog post to advertise the positions.

Once we identified potential candidates, we executed the following process:

  1. Requested a resume (or LinkedIn Profile URL) via e-mail.
  2. If skills and experience looked like a match, we sent a list of screening questions specific to the position.
  3. If screening answers were satisfactory, we'd schedule a face-to-face interview.
  4. We then conducted a face-to-face interview with a list of questions specific to the position.
  5. If convenient, we took the candidate to lunch to explore their social skills.
  6. After interviewing, the interviewers would huddle for 5-10 minutes and give thumbs-up/thumbs-down and we'd right up a summary e-mail for our boss.
  7. If thumbs-up, our boss would contact the candidate, discuss the details and extend an offer.

This process turned out to be a great way to hire a kick-ass team very quickly. You might notice that HR was not involved at all in this process. While we did use them to post jobs and such, we found that our recommendation-based process of identifying high-quality candidates worked much better. HR was able to bring in folks with lots of buzzwords on their resume, but no one knew them or what they were capable of.

Once a person passed the screening questions, our interview focused more on a person's social skills than their technical ability. The first half of the interview was all about their career experiences and what they enjoyed/disliked about employers and projects. The second half consisted of a handful of very technical, hard questions that we expected people to struggle with. If they answered correctly, we were impressed. If they didn't, we examined how they handled explaining they didn't know the answer. It was interesting to see how many people didn't simply answer "I don't know".

One of my most interesting observations of the process was our question about "what was your most enjoyable employment experience and why?" Most folks responded with something very early on in their career, and often it was their first job. This caused me to reflect on our industry and careers as a whole and wonder if people get more miserable as they keep working. It's a shame there's not more folks happy with their current jobs.

By mid-February, we managed to fill most of our open headcounts. We'd successfully hired 2 Agile Coaches and 8 Developers in a little over 2 months. While everyone hasn't started yet, there's several of us now working in my Denver office. We pretty much caught everyone off-guard with our success and we've moved onto our next biggest problem - were do we put everyone? The TWC Broomfield office is building out space for us, but it'll likely take them a few months to complete the project. My office that fits 4 comfortably had 8 of us in their last week. I had to sit on a garbage can when pairing because we'd run out of chairs.

To solve our short-term space constrains, I've successfully negotiated additional space upstairs from our landlady and we've ordered a number of new desks for folks. Our desks arrive Monday and we're setting up pairing stations upstairs next week. All-in-all, it's been a wild ride with a fair amount of stress. Interviewing folks wasn't that stressful, but trying to hire folks while writing code and trying to deliver features for our project was challenging.

We've been emphasizing pair programming and hiring process required a lot of e-mail communication. When we were pairing, we'd ignore our e-mails for most of the day and then have to catch up at night. Once people started on-boarding, we had to figure out the best way to get them started and slinging code. We established an on-boarding plan and we've been able to get everyone running our app on their machines before lunch. We've even had a couple folks committing code by the end of the first day.

This week, we on-boarded 3 of our final 4 developers. I breathed a big sigh of relief that the hiring was over and we could get back to slinging code and making things happen. As luck would have it, I received an e-mail from my boss on Tuesday that the hiring engine is starting up again and we need to hire 6 more developers. While I'm not anxious to start the Hiring Engine again, I am glad to know it works well and it has helped us build a great team. I'm not going to post the positions as part of this blog entry, but there's a good chance you'll hear more about the gigs if you follow me on Twitter.

Posted in Java at Mar 05 2010, 12:01:57 PM MST 5 Comments

My Future of Web Frameworks Presentation

Earlier this week, I tweeted about a history of web frameworks timeline I created for my upcoming Future of Web Frameworks talk at TSSJS Vegas 2010. I immediately received a lot of feedback and requests for adding new frameworks and releases. The image below is the result of that Twitter conversation. Thanks to everyone who contributed.

History of Web Frameworks

Back in November, I wrote about my proposals for TSSJS. I've been thinking a lot about web frameworks lately and I can't help but think we live in a very exciting time. As a Java developer, I've been exposed to one of the most vibrant language ecosystems on the planet. As Tim Bray talks about, the Java Platform has 3 legs: the language, the virtual machine and a huge, immense library of APIs (both in the JDK and in open source libraries). The diagram below is something I created based on Tim's podcast.

Java has 3 Legs

Tim says, "One of those legs is replaceable and that's the language." And he's right, there's many Java.next languages that run efficiently on the JVM. This is one of the most exciting parts of being a Java web developer today. There's many proven web frameworks and languages that you can pick to build your next web application.

The best part is many of the best web frameworks run on the JVM. Not only that, but the best code editors are the IDEs that you're familiar with and have grown to love. Furthermore, much of the literature for Java.next languages is written for Java developers. As someone who knows Java, you have wealth of web frameworks and languages just waiting for you to learn them.

To create my presentation on the future of web frameworks, I followed the outline I posted previously. I plan on explaining the evolution and history of web frameworks and how we got to where we are today. From there, I'll be speculating on what web applications we'll be developing in the future. Finally, I'll touch on the necessary features of web frameworks that will allow us to develop these applications.

Of course, I haven't actually presented this talk yet, so it's likely to change in the coming weeks before the conference. The good news is this gives you the opportunity to provide constructive criticism on this presentation and help make it better. I realize that a presentation rarely represents the conversation that takes place during a conference. However, I believe it can portray the jist of my thinking and lead to a meaningful conversation in the comments of this post. Below is the presentation I created - thanks in advance for any feedback.

For those who will be joining me at TSSJS ... it's gonna be a great show. St. Patrick's Day in Vegas, what more could you ask for? ;-)

Update: This article has been re-posted on Javalobby and contains additional community feedback in the comments.

Posted in Java at Feb 26 2010, 08:55:39 AM MST 5 Comments

Web Application Testing with Selenium by Jason Huggins

Selenium This evening, I attended Agile Denver's monthly meeting to listen to Jason Huggins talk about Selenium. The meeting started off with a panel on UI testing that I participated in. The most interesting part of this panel (for me) was meeting the other panelists and learning about their expertise. Folks from Red Pine Studios in Boulder video taped both the panel and presentation. Hopefully it will be published online in the near future.

Below are my notes from Jason's talk. Please keep in mind that most of these are his words, not mine.

Jason is the Executive Software Chef at Sauce Labs. He often experiments with new recipes and is one of the creators of Selenium. He worked at Google and helped them build and use a Selenium Farm to test Gmail and Google Docs. Selenium was inspired by ThoughtWorks Expense Report system and its "Add Row" button. The button caused so many issues, they needed a way to write a test that could be run in multiple browsers.

The first thing they tried was jWebUnit (a wrapper around HtmlUnit). Since HtmlUnit simulates the browser, it wasn't "real world" enough. The 2nd attempt was DriftWood. It was a Mozilla extension that drove a real browser so it could handle JavaScript UI features. The downside it was it didn't work for IE or Safari. It also used XML Syntax for tests. The 3rd attempt was JsUnit. It worked in all browsers, but its emphasis was on a single page unit test; it had no page-to-page workflow support. Also, you couldn't see what it was doing while it was running. The 4th attempt was FIT (Framework for Integration Testing). It allowed more readable tests, but the API wasn't that intuitive and there was too much magic behind the curtain. So basically, they had to fork FIT.

The first attempt was called "Selenese" and consisted of a 3-column table where each row had an Action, Target and Value. In the beginning, Selenium Core was a TestRunner that ran in any browser. It was written in plain ol' JavaScript and HTML. The next thing that came about was the Selenium IDE for Firefox. It maintains the echo of Selenium Core and FIT.

Selenium Remote Control (RC) was the next product produced by the project. Selenium RC allows you to write your tests in any language. A Selenium server interprets the requests and turns them into browser manipulation events. Finally, Selenium Grid was developed to leverage Selenium's HTTP architecture to allow parallel execution across servers.

Cloud computing is a wonderful use case for functional testing. Selenium Hub is a gateway into the Selenium Grid that routes the test request to particular browsers and platforms. Sauce Labs has a version of Selenium Grid that runs in the cloud.

Selenium Issues
Selenium is slow. Functional tests will always be slower than unit tests. Until the browsers can launch faster, there's always going to be speed issues. Parallel-ization can solve some of these and is something you should think about right away.

The JavaScript sandbox, Flash, Java Applets, Silverlight and Canvas all present problems in Selenium. Silverlight was shipped without any testing APIs. There are several libraries that provide a bridge for testing Flash. The Selenium project has though about including FlexMonkey, but its GPL license prevents it.

Practical Advice
Everyone seems to build a framework on top of Selenium. If you do this, make sure and write your DSL in terms of intent and then map it to Selenium actions.

Look for abstractions so you're not writing your Selenium tests with its API. It's too much like Assembler.

K.I.S.S. - don't write large tests, just do small ones. Often, when functional tests fail, they tell you something failed, but they don't tell you what failed. The shortest possible functional tests help reduce the scope of where a problem can be. Other benefits of short tests are they're easier to read and easier to write.

Selenium 2.0
The big thing in Selenium 2.0 is a merger with WebDriver. The nice thing about WebDriver is it gets rid of Selenium RC and allows you to drive the browser with a low-level API. For example, you use C++ to drive IE. Basically, every language will talk to the C driver. Except for Firefox, the connection and control is done through telnet. Selenium 2 should fix all the problems with Selenium 1, but also allow you to still use Selenium RC if you want to do grid-style testing.

Selenium 2's API is about finding elements and interacting with those elements. Also, it's entirely backwards compatible, so you can use the old API.

At this point, my laptop's battery died and I was unable to take any more notes. However, I was able to see some pretty slick demos, particularly Jason's company's Sauce onDemand cloud testing services. All you need to do to run your tests in the cloud is change how you initialize Selenium. A kick-ass feature this service provides is video playback (a.k.a. Castro). I'm currently using Selenium's screenshot functionality, but it doesn't hold a candle to the ability to watch a video playback of your tests. Jason also showed us a demo of using Castro and Selenium 2 to create a screencast on-the-fly. Very cool stuff.

My only question after seeing this talk is what's the difference between BrowserMob and Sauce Labs? Both companies were founded by Selenium committers and seem to offer competing projects. My gut feel is that BrowserMob is best for performance/load testing and Sauce Labs is best for running your tests in the cloud.

Posted in Java at Feb 15 2010, 09:44:44 PM MST 5 Comments

Web Application Testing with Selenium at Agile Denver next Monday

Next Monday evening, Jason Huggins will be in Denver to talk about web application testing with Selenium. Below is an outline of Jason's talk:

  • Overview of Selenium, what it does, what it doesn't do
  • How to get started with Selenium IDE, RC, and Grid
  • Why I started Sauce Labs (Selenium as a Cloud Service)
  • Selenium in 2010... Selenium 2
  • Future trends: Adobe Flex, mobile (iphone/ipad, android), HTML5 (canvas, video)
  • Best practices for succeeding with Selenium

This is an Agile Denver event and I'm really looking forward to it. Prior to Jason's talk (at 6:30), I'll be participating in a panel with several other Denver Testing Experts to discuss Selenium and related topics. This event will be held at the PPA Event Center (directions). We expect a great turnout, so make sure and get there early! For more information, see the meeting announcement.

On a related meetup note, don't forget next Tuesday's Denver Tech Meetup. Last month was a lot of fun and next week's meetup happens to land on Fat Tuesday. I can't think of a good reason not to come. ;-)

If you'd like to RSVP for the Denver Tech Meetup, please do so on LinkedIn or Facebook.

Posted in Java at Feb 11 2010, 08:55:51 AM MST Add a Comment

Using JRebel with IntelliJ IDEA on OS X

Yesterday afternoon, I figured out how to use JRebel with IntelliJ IDEA. I wrote up some AppFuse documentation for it at Using JRebel with IntelliJ IDEA and figured I'd repost it here for those developers using IDEA 9 and Maven.

  1. Download and install IntelliJ IDEA 9 Ultimate Edition (in /Applications on OS X).
  2. Download and install JRebel.
    1. java -jar jrebel-setup.jar
    2. Install the JRebel Plugin for IDEA. Shortcut: File > Settings > Search for plugins and find JRebel.
  3. On OS X, Modify /etc/launchd.conf and add the following so M2_HOME is available to GUI apps. You'll need to reboot after making this change.
    setenv M2_HOME /opt/tools/maven2
    

    More info on this setting is available on Stack Overflow.

  4. Modify your project's pom.xml to include the JRebel Maven plugin (for generating the configuration of which directories and files to watch for changes).
    <plugin>
        <groupId>org.zeroturnaround</groupId>
        <artifactId>javarebel-maven-plugin</artifactId>
        <version>1.0.5</version>
        <executions>
            <execution>
              <id>generate-rebel-xml</id>
              <phase>process-resources</phase>
              <goals>
                  <goal>generate</goal>
              </goals>
            </execution>
        </executions>
    </plugin>
    
  5. If you're using the Maven Jetty plugin, change your pom.xml so Jetty doesn't reload the app when classes are compiled. Specifically, change scanIntervalSeconds to 0. If you're not using this plugin, you should definitely check it out for Java webapp development.
  6. Use the JRebel icons to start jetty:run in your IDE. JRebel with IntelliJ IDEA
  7. Command Line Integration: Set a JREBEL_HOME environment variable that points to your JRebel install (/Applications/ZeroTurnaround/JRebel on OS X) and set your MAVEN_OPTS to use JRebel's settings. For example:
    export JAVA_OPTS="-Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true"
    export JREBEL_HOME=/Applications/ZeroTurnaround/JRebel 
    export MAVEN_OPTS="$JAVA_OPTS -noverify -javaagent:$JREBEL_HOME/jrebel.jar"
    

After making these changes, you should able to compile classes in IDEA and refresh your browser. Log messages like the following should show up in your console.

JRebel: Reloading class 'org.appfuse.webapp.action.UserAction'.

To simplify things further, you can map Command+S to compile (instead of Shift+F9). Just look for Keymaps in Settings, rename the default one and search for Compile to remap.

I'm assuming the steps to make things work on Windows and Linux are similar. Please let me know if you have any issues with these instructions.

Posted in Java at Feb 02 2010, 10:34:08 AM MST 3 Comments

Reviews for Grails: A Quick-Start Guide and Kanban and Scrum

A couple weeks ago, I had a business trip from Denver to Washington, DC. Since I didn't have any coding to do on the flight, I brought along a couple books and was surprisingly able to finish them both en route. Tech books that can be read in a single flight are my favorite. Another book I recall doing this with was First Steps in Flex back in December.

The books I read were Dave Klein's Grails: A Quick-Start Guide and Henrik Kniberg and Mattias Skarin's Kanban and Scrum minibook. Below are short reviews of each book.

Grails: A Quick-Start Guide
I've developed a few Grails applications, so I didn't expect to learn a whole lot from this book, but I was pleasantly surprised. Not only did it introduce all the basic concepts in a clear and concise way, it actually made it fun to read. The first chapter does a good job of introducing Groovy; showing you how to use closures and the easy-to-use collections API. From there, you dive into learning about the project, which is actually a real-life web application called TekDays.com. Then the foundational Iteration Zero is planned and executed.

In Chapter 3, you dive right into creating domain classes and their relationships. All the different mapping types are covered: one-to-one, one-to-many and the good ol' many-to-many. Since this is often a difficult part of an application, it's always nice to see how much Grails simplifies it. I liked the Ajax section in Chapter 7 and especially the part where it showed how to do a TagLib to show threaded comments in a forum.

Chapter 7 (Security) was a little disappointing in that it showed how to hand-roll your own security rather than using the Spring Security plugin (formerly Acegi) or the Shiro plugin (formerly JSecurity). I'd especially have liked to see how to do Ajax authentication where a token is generated for the client and included as a header in each subsequent request.

Other than that, I really enjoyed Chapter 10 where I learned how to implement search using dynamic finders, Hibernate's Criteria API and the Searchable Plugin (which gets its awesomeness from Compass). Implementing Compass in Java requires many, many annotations. In Grails, it's as simple as adding the following to your domain class.

static searchable = true

I truly enjoyed this book, especially with its Agile Development patterns that used iterations to get things done. Grails: A Quick-Start Guide is a code-intensive journey that gets up you to speed on Grails quickly and efficiently. It's very much like the framework itself. It eliminates the yak shaving and allows you learn without distractions. Kudos to Dave Klein for creating such an enjoyable and easy-to-read book.

Kanban and Scrum
In my career, I've used Scrum on quite a few projects. Of course, it's not the processes that typically make a team successful. Rather, it's often the gelling of the team members, as well as respect for coding practices that are proven to create higher quality code - specifically TDD and pair programming. Before reading this book, I'd heard a bit about Kanban, most of it from Marty Haught's Lean Teams: Doing more with less presentation.

This book did a great job of showing the differences between the two approaches: how Scrum promotes iterations whereas Kanban promotes cycle time. The most interesting part of the book is the Case Study in the 2nd half. This section shows how a team used various techniques to develop a well-oiled development machine. I think the most important thing to note from this section is how the team was willing to change, learn and grow based on their experiences - in a very rapid fashion.

In my current gig, I'm helping a team of developers move from waterfall to agile processes. We're leveraging many aspects of Scrum and agile by using a coach, iterations, daily standups, TDD, continuous integration and creating "as built" documentation when we finish developing a feature. The "As Built" documentation is something I picked up from working at Chordiant and I've found it to be a great way of education developers (and outsiders) how things were done in an iteration.

One thing we've seen in our first few weeks is that iterations don't work for all teams or individuals. A Kanban model fits much better for them. Having a Kanban board allows them to visualize (and control) their workload in a much more efficient manner. We haven't started implementing actual boards on a wall, we're just using spreadsheets for now. However, we do have two Agile Coaches starting this week so I expect things to improve rapidly.

Back to the book. More than anything, I enjoyed reading this book because it made me excited about the changes I'm helping implement and I believe in many of the practices in both Scrum and Kanban. I enjoy iterations and structured expectations around development, but I can see how Kanban would work better for folks in operations and infrastructure. I look forward to implementing the best parts of both worlds and hopefully a similar Case Study of what worked and what didn't. With any luck, we'll be able to learn, evolve and produce at a much higher level than previous waterfall practices achieved.

Posted in Java at Feb 01 2010, 09:29:40 AM MST 5 Comments

What's your preferred development infrastructure stack?

Over the years, I've used many different source control systems, wikis, bug trackers and continuous integration servers. On many projects, I've been responsible for recommending and helping to install these systems. For the most part, they've often been disparate, meaning there wasn't a whole lot of integration between the various applications. Here's a list of all the different systems I've used:

I believe all of these applications are useful in supporting an efficient development process. When clients have asked me to help them build this type of infrastructure, I've often asked if they wanted to pay for it or not. If not, I'd recommend Trac (since it has a wiki, source viewer and bug tracker all-in-one) and Hudson. If they were willing to pay, I'd recommend the Atlassian Suite (Confluence, JIRA and Bamboo).

These stacks all seem to work pretty well and the Atlassian Suite certainly works great for AppFuse and other open source projects. However, I recently had the pleasure of working at Chordiant Software where we used Chordiant Mesh to collaborate and develop software. Their Mesh system is powered by Jive Clearspace and provides a wealth of tools for each project, including a dashboard, discussions, documents, notifications and widgets providing status + links to JIRA and Bamboo.

Even though Clearspace's rich text editor caused me some early frustration, I really enjoyed the fact that a solid development infrastructure existed. It made it much easier to collaborate, document and execute our development process. I realize that it's difficult to build and maintain a custom development infrastructure stack. Chordiant had a whole team that developed, enhanced and supported their environment. But that doesn't mean it's impossible and not worth striving for.

I think there's a number of best-of-breed applications you can use to build a sweet development infrastructure stack.

  • Source Control: Git
  • Source Viewer: FishEye
  • Wiki: Jive SBS
  • Bug Tracker: JIRA
  • Continuous Integration: Hudson

I've only used Git for a few weeks, but I can easily tell it's better than Subversion. I don't think it's easy to convince companies to switch their source control system, so it's probably not worth arguing if you're already using Subversion. I can also envision using Confluence instead of Jive SBS, but then you lose forum support and have to use something like Mailman or Google Groups. JIRA Studio looks close to my dream stack, except it doesn't support Git or a forum + mailing list system.

What is your preferred development infrastructure stack? Why?

Posted in Java at Jan 12 2010, 09:54:46 PM MST 30 Comments

Grails OAuth and LinkedIn APIs

Back in November, I wrote about how to talk to LinkedIn APIs with GWT. A week later, I figured out how to do it with Grails and contributed a patch to the grails-oauth plugin.

Since then, a few folks have asked how I did it. Since code speaks louder than words, I took some time and 1) verified the oauth plugin works as expected and 2) created an example application demonstrating functionality. You can find the results in my fork of grails-oauth on GitHub. You can also view the example online.

Below is a quick tutorial explaining how to integrate LinkedIn into your Grails application.

  1. Download and install Grails 1.1.2.
  2. Run grails create-app to create your application.
  3. Add the following to the bottom of grails-app/conf/Config.groovy:
    oauth {
        linkedin {
            requestTokenUrl="https://api.linkedin.com/uas/oauth/requestToken"
            accessTokenUrl="https://api.linkedin.com/uas/oauth/accessToken"
            authUrl="https://api.linkedin.com/uas/oauth/authorize"
            consumer.key="XXX"
            consumer.secret="XXX"
        }
    }
    
    You can get your consumer.key and consumer.secret at https://www.linkedin.com/secure/developer. Make sure to set the OAuth Redirect URL to http://localhost:8080/{your.app.name}/oauth/callback for testing.
  4. Download the oauth-plugin, extract it and build it using grails package-plugin. Install it in your project using grails install-plugin path/to/zip.
  5. Add a link to the GSP you want to invoke LinkedIn Authentication from:
    <g:oauthLink consumer='linkedin' returnTo="[controller:'profile']">
        Login with LinkedIn
    </g:oauthLink>
    
  6. Create grails-app/controllers/ProfileController.groovy to access your LinkedIn Profile.
    class ProfileController {
        def apiUrl = "http://api.linkedin.com/v1/people/~"
        def oauthService
        
        def index = {
     
            if (session.oauthToken == null) {
                redirect(uri:"/")
            }
     
            if (params?.apiUrl) apiUrl = params.apiUrl
            
            def response = oauthService.accessResource(
                    apiUrl, 'linkedin', [key:session.oauthToken.key, secret:session.oauthToken.secret], 'GET')
     
            render(view: 'index', model: [profileXML: response, apiUrl: apiUrl])
        }
     
        def change = {
            if (params?.apiUrl) {
                println("Setting api url to " + params.apiUrl)
                apiUrl = params.apiUrl
            }
            
            redirect(action:index,params:params)
        }
    }
    
  7. Create grails-app/views/profile/index.gsp to display the retrieved profile and allow subsequent API calls.
    <html>
    <head><title>Your Profile</title></head>
    <body>
    <a class="home" href="${createLinkTo(dir:'')}">Home</a>
    <g:hasOauthError>
        <div class="errors">
            <g:renderOauthError/>
        </div>
    </g:hasOauthError>
    
    <g:form url="[action:'change',controller:'profile']" method="get">
        Your LinkedIn Profile:
        <textarea id="payload" style="width: 100%; height: 50%; color: red">${profileXML}</textarea>
        <p>
            <g:textField name="apiUrl" value="${apiUrl}" size="100%"/>
            <br/>
            <g:submitButton name="send" value="Send Request"/>
        </p>
    </g:form>
    </body>
    </html>
    
  8. Start your app using grails run-app and enjoy.

As mentioned earlier, you can download the grails-oauth-example or view it online.

One improvement I'd like to see is to simplify the parsing of XML into a Profile object, much like the linkedin gem does for Rails.

If you're interested in learning more about LinkedIn and OAuth, I encourage you to checkout Taylor Singletary's presentation LinkedIn OAuth: Zero to Hero.

Update: I updated the oauth-plugin so it's backwards-compatible with OAuth 1.0 and added Twitter to the example application to prove it. If you're seeing "Cannot invoke method remove() on null object", it's likely caused by your redirect URL pointing to an application on a different domain.

Posted in Java at Dec 22 2009, 03:37:57 PM MST 7 Comments

Comparing Kick-Ass Web Frameworks at The Rich Web Experience

Yesterday, I delivered my Comparing Kick-Ass Web Frameworks talk at the Rich Web Experience in Orlando, Florida. Below are the slides I used:

Although it's difficult to convey a presentation in a slide deck, I can offer you my conclusion: there is no "best" web framework. I believe web frameworks are like spaghetti sauce in that everyone has different tastes and having so many choices is necessary to satisfy everyone. You can read more about the plural nature of perfection in Malcolm Gladwell's The Ketchup Conundrum (a written version of What we can learn from spaghetti sauce). Even though there is no "best" web framework, I believe GWT, Flex, Rails and Grails are frameworks that every web developer should try. They really do make it fun to develop web applications.

You can find the slides for my other RWE talk at Building SOFEA Applications with GWT and Grails.

Kudos to Jay Zimmerman for putting on a great show in Orlando this year. I had a great time talking with folks and learning in the sessions I attended. I particularly enjoyed bringing my parents and kids and staying at such a nice resort. Disney World (Magic Kingdom) and Universal Studios was very enjoyable due to the short lines. Also, the weather was perfect - especially considering the freezing cold in Denver this week. ;-)

Posted in Java at Dec 04 2009, 08:16:48 AM MST 3 Comments

AppFuse 2.1 Milestone 1 Released

The AppFuse Team is pleased to announce the first milestone release of AppFuse 2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are Hibernate, Spring and Tapestry 5.

What is AppFuse?
AppFuse is an open source project and application that uses open source tools built on the Java platform to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time found when building new web applications for customers. At its core, AppFuse is a project skeleton, similar to the one that's created by your IDE when you click through a wizard to create a new web project.

Release Details
Archetypes now include all the source for the web modules so using jetty:run and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose which persistence framework (Hibernate, iBATIS or JPA) you'd like to use. If you want to modify the source for that, add the core classes to your project or run appfuse:full-source.

In addition, AppFuse Light has been converted to Maven and has archetypes available. AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The light archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket.

Other notable improvements:

Please note that this release does not contain updates to the documentation. Code generation will work, but it's likely that some content in the tutorials won't match. For example, you can use annotations (vs. XML) for dependency injection and Tapestry is a whole new framework. I'll be working on documentation over the next several weeks in preparation for Milestone 2.

AppFuse is available as several Maven archetypes. For information on creating a new project, please see the QuickStart Guide.

To learn more about AppFuse, please read Ryan Withers' Igniting your applications with AppFuse.

The 2.x series of AppFuse has a minimum requirement of the following specification versions:

  • Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)
  • Java 5+

If you have questions about AppFuse, please read the FAQ or join the user mailing list. If you find bugs, please create an issue in JIRA.

Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues.

Posted in Java at Nov 19 2009, 07:16:36 AM MST 8 Comments