Matt RaibleMatt Raible is a writer with a passion for software. 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.
You searched this site for "young russian teenboy model pre teen". 788 entries found.

You can also try this same search on Google.

A Webapp Makeover with Spring 4 and Spring Boot

A typical Maven and Spring web application has a fair amount of XML and verbosity to it. Add in Jersey and Spring Security and you can have hundreds of lines of XML before you even start to write your Java code. As part of a recent project, I was tasked with upgrading a webapp like this to use Spring 4 and Spring Boot. I also figured I'd try to minimize the XML.

This is my story on how I upgraded to Spring 4, Jersey 2, Java 8 and Spring Boot 0.5.0 M6.

When I started, the app was using Spring 3.2.5, Spring Security 3.1.4 and Jersey 1.18. The pom.xml had four Jersey dependencies, three Spring dependencies and three Spring Security dependencies, along with a number of exclusions for "jersey-spring".

Upgrading to Spring 4
Upgrading to Spring 4 was easy, I changed the version property to 4.0.0.RC2 and added the new Spring bill of materials to my pom.xml. I also add the Spring milestone repo since Spring 4 won't be released to Maven central until tomorrow.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>${spring.framework.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <url>http://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>
[Read More]

Posted in Java at Dec 11 2013, 12:47:15 PM MST 7 Comments

Devoxx 2013 + a Nordic Countries Speaking Tour

Trish at Pelgrom Two weeks ago, Trish and I boarded a flight for one of our favorite conferences: Devoxx. After a brief layover in Frankfurt, we arrived in Amsterdam and took a train to Antwerp. Within hours, we'd settled into our hotel near the center of Antwerp and strolled over to the dungeonous, yet cozy, Pelgrom restaurant. We were hoping for a delicious dinner, but found much more. We ran into James Ward, Dick Wall and a number of other enthusiastic speakers from the conference. Since I had to speak the next day, we didn't stay long, but we did share a number of laughs with some great people.

Tuesday (November 12), was a University Day at Devoxx, and I had my talk that afternoon. I spent a couple hours finishing up my talk that morning, then grabbed a taxi to head to the conference. I was honored with the opportunity to speak in Room 8, which is a huge theater that holds several hundred people.

Devoxx: A Speaker's Perspective The Modern JVM Web Developer AngularJS Deep Dive

I presented a lengthened version of The Modern Java Web Developer presentation I did early this year (at Denver's JUG and JavaOne). Based on your feedback, I chose to do deep dives on AngularJS, Bootstrap and Page Speed. I've always enjoyed speaking at Devoxx because attendees are so enthusiastic and passionate about the conference. I received an immense amount of feedback, both in praises and criticisms. The critics indicated there were too many buzzwords and not enough substance. Others complained that the AngularJS Lipsync that I did was too deep.

I made sure to review and process everyone's comments, and then used them to improve the presentation throughout the following week. I learned to elaborate on the fact that many of the technologies were important to know about, but not important to know through-and-through. I made sure to mention that the use of CoffeeScript and LESS is often limited (or embraced) by team members and their willingness to try new things. If you're not writing thousands of lines of JavaScript or CSS, it probably doesn't make sense to use these languages. Furthermore, if your team members are struggling to write JavaScript or CSS, introducing a new language is probably not the best thing. I also reminded people to be skeptical of new technology, but also to be open-minded and give everything a chance. The 10-minute, download-and-try test, is a great way to do that.

You can find my presentation below, download it from my presentations page, or view it on SlideShare.

Within this presentation, there are links to each of the deep dives. The last two are screencasts that I added audio to a few days ago.

Bootstrap 3 | AngularJS Deep Dive | Page Speed Demo

[Read More]

Posted in Java at Nov 28 2013, 12:07:26 PM MST Add a Comment

Developing with AngularJS - Part IV: Making it Pop

Welcome to the final article in a series on my experience developing with AngularJS. I learned its concepts, beat my head against-the-wall with and finally tamed it enough to create a "My Dashboard" feature for a client. For previous articles, please see the following:

The last mile of development for the My Dashboard feature was to spice things up a bit and make it look better. We hired a design company to come up a new look and feel and they went to work. Within a week, we had a meeting with them and they presented a few different options. We picked the one we liked the best and went to work. Below are screenshots that I used to implement the new design.

My Dashboard - New Design My Dashboard with Show More

[Read More]

Posted in The Web at Sep 12 2013, 10:54:29 AM MDT 7 Comments

Developing with AngularJS - Part III: Services

This is the 3rd article in a series on my experience developing with AngularJS. I used AngularJS for several months to create a "My Dashboard" feature for a client and learned a whole bunch of Angular goodness along the way. For previous articles, please see Part I: The Basics and Part II: Dialogs and Data.

Angular offers several ways to interact with data from the server. The easiest way is to use the $resource factory, which lets you interact with RESTful server-side data sources. When we started the My Dashboard project, we were hoping to interact with a REST API, but soon found out that it didn't have all the data we needed. Rather than loading the page and then making another request to get its data, we decided to embed the JSON in the page. For communication back to the server, we used our tried-and-true Ajax solution: DWR.

In Angular-speak, services are singletons that carry out specific tasks common to web apps. In other words, they're any $name object that can be injected into a controller or directive. However, as a Java Developer, I tend to think of services as objects that communicate with the server. Angular's documentation on Creating Services shows you various options for registering services. I used the angular.Module api method.

[Read More]

Posted in The Web at Jun 25 2013, 07:03:26 AM MDT 10 Comments

Video of Comparing JVM Web Frameworks from Devoxx France

Whenever I do a talk, I get requests for a recording of it. It's rare that recordings are made, but when they are, I like to share them. In March of this year, I traveled to Devoxx France and had a great time. One of the talks I delivered was Comparing JVM Web Frameworks, with a bit of a twist from prior versions.

The Paradox of Choice I started reading The Paradox of Choice and found many parallels to the agony that developers experience with choosing a web framework. I described how I didn't think good framework decisions were based on the many, many features that frameworks have, but often on pre-defined constraints. There's those lucky developers that get to choose a Full Stack Framework because they're doing greenfield development. Then there's those that want a better Pure Web Framework that replaces something (e.g. Struts) that's not satisfying their needs. And lastly, there's those that've found it possible to leverage a SOFEA and use a JavaScript MVC framework with an API Framework on the backend. I don't think it makes sense to compare all web frameworks and I tried to use these pre-defined constraints (language, platform and application type) argument to separate into categories and help make choosing easier.

The good folks at Parleys have published the video of this talk. If you haven't heard of Parleys, it's an awesome platform for watching conference talks. As their Mission Statement says: If YouTube and Slideshare would make a baby then it would be named Parleys.

Below is an embedded video of this presentation - I hope you enjoy watching it as much as I did delivering it!

Posted in Java at Jun 24 2013, 09:10:45 AM MDT Add a Comment

Developing with AngularJS - Part II: Dialogs and Data

A couple of days ago, I wrote an article on how I started developing with AngularJS. I used AngularJS for several months to develop a "My Dashboard" feature for a client's product and learned a whole bunch of stuff along the way.

This article provides an overview of how I changed some of My Dashboard's features to use Angular instead of jQuery. After finishing the prototype work in January, we started moving bits and pieces into the main application. We kept the same file names for our Angular-related files and copied them into the project.

Directory Structure

All these files are packaged up into a dashboard.js file that's included at the bottom of our Dashboard page. While our prototype used jQuery 1.9 and jQuery UI 1.10, the application's codebase used jQuery 1.7.1 and jQuery UI 1.8.3. Luckily, this didn't present a problem as everything continued to work as expected.

Around this time, we also had many discussions with the Product Team about charts. Since Highcharts required we purchase a license, we took at look at AnyChart, which we were already using. We were able to get AnyChart to work with our existing chart directive with minimal changes. Most changes were in the JSON itself.

We committed the first pass (with sample data still hard-coded) in mid-February.

[Read More]

Posted in The Web at Jun 20 2013, 08:45:13 AM MDT 4 Comments

Developing with AngularJS - Part I: The Basics

There's many, many different introductions to AngularJS available on the internet. This article is not another introduction, but rather a story about my learning experience. It all started way back in January of this year. I was working as a UI Architecture Consultant at Taleo/Oracle, my client for the last 21 months. My gig there ended last month, but they agreed to let me publish a series of articles about the knowledge I gained.

Project Background

The Director of Product Management had been working on the concepts for a new project - codenamed "Visual MyView". Below is a mockup he created for our kickoff meeting on January 4th.

My Dashboard - Original Mockup

From his original email about the above mockup:

The intent here is that one of the columns has rows that have a similar width. The rows could be dragged and dropped into a different order – or potentially the two columns could also be reordered. The rows will basically be comprised of similar widgets. You can see in the mockup how the first two rows might look – and sample widgets. The widgets shown can be configured by the end user, as well as the order in which they are displayed. Other requirements given to us were the following.

  • Row 1 is comprised of 'summary' widgets that are 'todo' items. Reviews needing done – approvals required – etc.
  • Row 2 will be a graph row – having graphs and charts to display information – larger squares will build this row.
  • Row 3's content was not determined yet.

I started the initial layout with static HTML and CSS and had a wireframe to show by mid January.

Wireframe

By the end of January, we'd renamed the project to My Dashboard and had a working prototype using CoolClock and moment.js for the clock in the top right, AngularJS to display widget data, jQuery UI for drag-n-drop of rows and widgets, Bootstrap's Carousel for holding charts and Highcharts for rendering charts.

[Read More]

Posted in The Web at Jun 18 2013, 09:06:52 AM MDT 9 Comments

Responsive Design with CSS Media Queries

In preparation for my upcoming talk on Bootstrap and CSS3, I figured it was high time I made this blog responsive. Making my new theme mobile-friendly has been on my todo list ever since last year's redesign. I also took the opportunity to 1) remove the geolocation lookup and associated sunset logic for theme selection and 2) change the default theme to the "light" one. If you prefer dark, just click on the black rectangle in the top-right.

I started by refreshing my knowledge of media queries by reading CSS Media Queries & Using Available Space. This led me to John Hick's site, where I grabbed a couple of his rules. Most notably, I started optimizing for iPhone, smartphones and any screens less than 1000px wide. I also decided to widen things a bit for larger screens.

/* Smartphones */
@media handheld and (max-width: 480px), screen and (max-device-width: 480px), screen and (max-width: 1000px) {

}

/* Large Desktop */
@media screen and (min-width: 1200px) {

}

When I started hacking away, I noticed a lot of the elements had "width" hard-coded in pixels, so I changed a lot of these to use "max-width" instead, as well as "width: 100%". This allowed me to only have a few elements that controlled the width and I was able to take advantage of larger screens with the following simple rules.

@media screen and (min-width: 1200px) {
    #site-container, #body-content, #header-inner {
        max-width: 1170px;
    }

    #body-content #left-column, .next-previous {
        max-width: 808px;
    }
}

For smartphones, I started by hiding the right column and menus with display: none. Then I decided the navigation menu might be useful if I ever wanted to manage the site on my phone. I found Create an Absolute Basic Mobile CSS Responsive Navigation Menu from the treehouse blog and went to work. 20 minutes later, I had the menu I was looking for and everything was looking pretty good in iOS Simulator.

raibledesigns.com on iOS Simulator

At this point, I discovered that rotating to landscape mode caused the content font to become quite a bit larger. So I added a rule for the iPhone in landscape mode.

/* iPhone Landscape */
@media screen and (min-width: 321px) and (max-width: 480px) and (orientation: landscape) {
    #body-content #left-column .article .contents {
        font-size: 9px;
    }
}

I'm still not sure why this happens. I also noticed that rotating back to portrait causes some empty whitespace to show up on the right. The empty whitespace was a problem I spent most of my time solving. I ended up using web inspector with iOS Simulator to figure out which elements were bleeding past my desired width and then adjusted their width, or used overflow: hidden to hide them.

I enjoyed this mobile design experience, even with the many "why is there whitespace there!" moments. I especially liked it when I found I didn't need any rules for the iPad. I'm sure there's a few issues that still exist. For example, I haven't tested it on an Android device. Also, the Facebook button's "color-scheme" is still hard-coded in my templates. I hope to fix this by patching Roller to allow reading cookies on the server-side. If you notice anything that looks funny, please let me know.

In the meantime, I hope you enjoy squishing and stretching your modern browser to see how this new responsive design works.

Posted in Roller at Apr 10 2013, 11:38:12 AM MDT 3 Comments

Devoxx France: A Great Conference in a Magnificent City

Red Eiffel flowers This week, my lovely fiancé and I traveled to the City of Light. Our journey was designed around some speaking engagements at Devoxx France. Devoxx is one of my favorite conference franchises and Devoxx France has been special to me ever since the Devoxx (Belgium) I spoke at in 2011.

2011 was the year I spoke about my experience with Play, Scala, CoffeeScript and Jade. I wrote the presentation on my flight over, composed the demo video the night before and made it all happen in the nick of time. Of course, this was after 120 hours of research and preparation, so the presentation composition process had all the data I needed. You can imagine my sense of relief after pulling off that talk and getting an enthusiastic applause from the audience for my efforts.

One of the first audience questions I received was from Nicolas Martignole, asking if I'd speak at Devoxx France the following year. I whole-heartedly agreed to do it and was excited for the opportunity. It was with great disappointment that I later found out I couldn't attend Devoxx France in 2012. My client didn't like me taking so much time off and I agreed to scale my two week vacation back to 1 week. This year, I was determined to go, so I submitted some of my favorite talks: Comparing JVM Web Frameworks and The Play vs. Grails Smackdown with James Ward. I was extremely pleased when they both got accepted.

Side Story: I met Martin Odersky shortly when he sat down next to me for the Java Posse presentation in Belgium in 2011. After shaking his hand and introducing myself, I had to politely ask him to leave because it was Trish's seat. Talk about awkward; but Martin was very gracious and promptly found a new seat close by.

The Paradox of Choice Comparing JVM Web Frameworks
Both talks required a bit of updating. For Comparing JVM Web Frameworks, I started reading The Paradox of Choice and found many parallels to the agony that developers experience with choosing a web framework. I described how I didn't think good framework decisions were based on the many, many features that frameworks have, but often on pre-defined constraints. There's those lucky developers that get to choose a Full Stack Framework because they're doing greenfield development. Then there's those that want a better Pure Web Framework that replaces something (e.g. Struts) that's not satisfying their needs. And lastly, there's those that've found it possible to leverage a SOFEA and use a JavaScript MVC framework with an API Framework on the backend. I don't think it makes sense to compare all web frameworks and I tried to use these pre-defined constraints (language, platform and application type) argument to separate into categories and help make choosing easier.

I took out the parts of the presentation that've pissed people off in the past - particular the JSF bashing by James Gosling, the Rails gushing from Craig McClanahan and the Pros and Cons sections of each framework. I added the history of web frameworks and research from InfoQ and devrates.com.

History of Web Frameworks 2013

The best part of the JVM Web Frameworks talk was the audience's reaction and enthusiasm. Devoxx always seems to attract passionate developers and Devoxx France was no different. Developers packing the room, clapping after your intro, laughing at your jokes, signifying that they agree with you about JSF. As a speaker, it's an unbelievable experience.

You can view my Comparing JVM Web Frameworks presentation below or on Slideshare.net.

Play Frameworks vs. Grails Smackdown
To prepare for James Ward and my Play vs. Grails Smackdown, we had a number of goals. First of all, we wanted to update our apps to use the latest versions of each framework. I documented what it took for Grails, James just checked in his code to GitHub. It was interesting to see that Grails 2.0.3 -> 2.2.1 caused a number of issues with testing, while Play 2.0.3 -> Play 2.1.0 required API changes, but nothing for tests. Secondly, we updated all the stats for our pretty graphs and ran load tests again.

This is where the fun started. On Tuesday evening, I decided to challenge the notion that Play was twice as fast as Grails. James had proven this with Apache Bench tests. With Play 2.0 and Grails 2.0 (last summer), we clocked Play at 251/requests per second and 198 for Grails. After upgrading each app to the latest releases, we found the numbers to be 233/second for Play and 118 for Grails.

However, Apache Bench only tests until the first byte is received. Since I've done a lot of browser optimizations recently, I fired up whichloadsfaster.com, captured a screenshot and added it to our presentation. The next day, James added a CDN and a bunch of caching to his app and re-ran his AB tests.

Now he was smoking Grails, so I added a CDN and caching as well. However, the best I could do was just over 1000/requests per second, while he was around 2200/second. When he ran live tests during our talk, Play was around 2800/sec and Grails was around 900.

It was great to see how much better performance we could get with caching and a CDN. The best part is this should be available to most applications, not just these frameworks. By adding a CDN (we used Amazon CloudFront) and caching, we were both able to 10x the performance of our apps. You can find our presentation here or view it below.

Summary
This was a very enjoyable conference to attend as a speaker. First of all, it was in one of the most beautiful cities in the world, but it's also a very special place for Trish and I. We got engaged just outside of Paris in Versailles after the last Devoxx conference I spoke at. Trish has some amazing photos from that trip. Secondly, the Devoxx conference attracts a special kind of developer - one that is passionate about and eager for knowledge. Lastly, speaking with my good friend James, in an exotic city about something we love - that was special. Asking for beers and having them brought to us at the start of our Smackdown. That was magical (thanks Nicolas!).

To all the Devoxx organizers and crew - well done on a great show!

Posted in Java at Mar 29 2013, 01:14:30 PM MDT 3 Comments

Upgrading Grails from 2.0 to 2.2

Grails In preparation for my Grails vs. Play Smackdown at Devoxx France next week, I recently upgraded my Grails version of Happy Trails from Grails 2.0.3 to Grails 2.2.1. I ran into a few issues along the way and figured I'd document them here to help others out.

Fixing the source
The first issue I ran into was Spock and Groovy 2 incompatibilities.

| Resolving plugin JAR dependencies
| Error WARNING: Dependencies cannot be resolved for plugin [mail] due to error: startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/Users/mraible/.grails/ivy-cache/org.spockframework/spock-core/jars/spock-core-0.7-groovy-1.8.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 0.7.0-groovy-1.8 is not compatible with Groovy 2.0.7. For more information, see http://versioninfo.spockframework.org

I posted the problem to StackOverflow and got a response almost immediately. While this pull request helped me quite a bit, it was ultimately caused by my vision: I had two "geb-spock" dependencies listed in BuildConfig.groovy with different groupIds.

At this point, I also moved all my plugin dependencies from application.properties to BuildConfig.groovy.

The next problem I ran into was a unit test and functional tests failing. The unit testing issue was caused by my Direction model not being in the tests @Mock annotation. After I added it, validation kicked and I recognized my test was invalid. I added @Ignore and continued.

The functional test seemed to be seemed to be caused by Geb and it trying to use the Chrome Driver. One of my tests didn't work with the default HtmlUnitDriver, so I used the ChromeDriver for the one test.

| Running 11 spock tests... 6 of 11
| Failure:  signup as a new user(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.WebDriverException: Unable to either launch or connect to Chrome. Please check that ChromeDriver is up-to-date. Using Chrome binary at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.66 seconds
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.2', java.version: '1.7.0_04'
Driver info: org.openqa.selenium.chrome.ChromeDriver
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:115)
    at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:161)
    at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:107)
    at happytrails.AuthenticatedUserSpec.signup as a new user(AuthenticatedUserSpec.groovy:25)

Even when running "grails -Dgeb.env=chrome test-app", this still happened. This was caused by the fact that I had GebConfig.groovy in test/functional/happytrails. Move it to test/functional solved the problem. I also discovered that I know longer needed Chrome to get this test to pass. Apparently, the HtmlUnitDriver has issues with Grails 2.2, but it seems to work for me.

After getting the Geb configuration fixed, I ran into a functional test failure:

| Running 11 spock tests... 5 of 11
| Failure:  click signup link(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.ElementNotVisibleException: Element must be displayed to click (WARNING: The server did not provide any stacktrace information)

Even though I could see the "signup" link when I ran "grails run-app", I could see that it didn't show up when running tests in Chrome. This turned out to be caused by an extraneous <div class="nav-collapse"> I had in my main.gsp. Removing it solved the problem. It's strange that this never showed up with Grails 2.0. My only guess is that Geb someone didn't look at the visibility of the element.

The last testing-related issue I ran into was a InvalidElementStateException:

| Running 11 spock tests... 7 of 11
| Failure:  add new route to region(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.InvalidElementStateException: Element must be user-editable in order to clear it. (WARNING: The server did not provide any stacktrace information)

I was able to fix this by changing AddRoutePage.groovy from:

static content = {
    createButton(to: ShowRoutePage) { create() }
    name { value("Name") }
    distance { value("Distance") }
    location { value("Location") }
}

To:

static content = {
    createButton(to: ShowRoutePage) { create() }
    form { $("form") }
}

And then referencing name, distance and location accordingly (form.name, etc.) in AuthenticatedUserSpec.groovy.

CloudBees
After I had everything working locally, I logged into Jenkins on CloudBees. Since I hadn't used it in a while, I had to wait a bit while my Jenkins server was re-commissioned. Once it was up, I tried to select Grails 2.2.1 to build with, but found it wasn't available. After a tweeting this, I learned about Grails Wrapper, found that the latest Grails Jenkins plugin supported it and got everything working. I later discovered that CloudBees does support Grails 2.2.1, I just needed to setup another Grails installation to automatically download and install 2.2.1.

Heroku
The last two issues I ran into were with Heroku. Since I was upgrading everything, I wanted Grails to build/run under Java 7 and use Servlet 3. I changed the appropriate properties in BuildConfig.groovy, configured Heroku and deployed. No dice.

Error Compilation error: startup failed:
Invalid commandline usage for javac.
javac: invalid source release: 1.7
Usage: javac  
use -help for a list of possible options

Sidenote: I tried building with Java 8 on CloudBees, but discovered the searchable plugin doesn't support it.

Compile error during compilation with javac.
/scratch/jenkins/workspace/Happy Trails - Grails 2/work/plugins/searchable-0.6.4/src/java/grails/plugin/searchable/internal/compass/index/DefaultUnindexMethod.java:94: error: reference to delete is ambiguous
                    session.delete(query);
                           ^
  both method delete(CompassQuery) in CompassOperations and method delete(CompassQuery) in CompassIndexSession match

As far as Servlet 3, it was pretty obvious that the Jetty version Heroku uses for Grails doesn't support it. Therefore, I reverted back to Servlet 2.5.

java.lang.NoClassDefFoundError: javax/servlet/AsyncContext
	at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)

I sent the Java 7 issue to Heroku Support a few days ago but haven't heard back yet.

Summary
While upgrading Grails from 2.0 to 2.2 wasn't as easy as expected, it is understandable. After all, Grails 2.2 ships with Groovy 2.0, which has a bunch of new features itself. All the issues I ran into were fairly easy to solve, except for Java 7 on Heroku. But hey, what do you expect from a free hosting service?

If you're at Devoxx France next week, I look forward to sharing our research on Grails 2.2.1 vs. Play 2.1.0.

Posted in Java at Mar 22 2013, 09:16:37 AM MDT 2 Comments