The Angular Mini-Book is a
guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and
deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.
Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with
Spring Boot and use security best practices like HTTPS and a content security policy.
This book shows you how to build an app with JHipster, and guides you through the
plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks
so you understand the underpinnings of your great application.
I recently received an email from a long time follower of my comparing web frameworks research and presentations. He asked some interesting questions:
I am starting on a new venture to build a direct to consumer web application. I am planning to leverage Cloud services to build my CI/CD pipeline. I am very strong with Java Backend/middleware and learning Javascript Front-end frameworks. I love Spring and SOFEA. Having said that, I am wondering if I should use Grails + Angular or JHipster? My primary concern with JHipster is there is hardly any ‘community', there is Julien and whatever he says/thinks goes! Can you give me some pointers?
I imagine there's other JVM developers with similar questions, so I figured I'd publish my response for all to see.
JHipster may have a smaller community than Grails, but remember that it's built on Spring Boot and AngularJS. Both have huge communities. In fact, Grails 3 is built on Spring Boot, just like JHipster.
Even though JHipster generates your code in Java, there's nothing preventing you from writing your code in Groovy or Scala. I dig JHipster, but I've also worked with AngularJS and Spring Boot for a couple years. The fact that someone put these technologies together and makes it easy to work with them is awesome.
I like JHipster so much, I decided to write a book on it. I hope to finish it in the next couple months and have it published in the fall. It'll be a free download from InfoQ. Learn more at http://www.jhipster-book.com.
Yes, I'm probably a bit biased since I'm writing a JHipster book. However, it's been easy for me to introduce and use Spring Boot at my last few clients. They were already using Spring, so the transition to using a Spring simplifier was a no-brainer. I haven't had as much luck getting clients to adopt Grails, even though I've suggested it. That could change now that it's based on Spring Boot.
What's your experience? Would you recommend Grails + Angular over JHipster? If so, why?
A couple months ago, I was invited to speak at Virtual JUG - an online-only Java User Group organized by the ZeroTurnaround folks. They chose my Comparing JVM Web Frameworks presentation and we agreed I'd speak yesterday morning. They used a combination of Google Hangouts, live streaming on YouTube and IRC to facilitate the meeting. It all went pretty smoothly and produced a comfortable speaking environment. To practice for vJUG, I delivered the same talk on Tuesday night at the Denver Open Source Users Group.
I also updated all the pretty graphs (which may or may not have any significance) with the latest stats from Dice.com, LinkedIn, StackOverflow and respective mailing lists. Significant changes I found compared to one year ago:
This year marked my first time speaking at JavaOne. It seems to have gone well, especially since audience feedback resulted in a JavaOne Rock Star Award. I'm very humbled to be listed with some really great speakers. Congratulations to all the other Rock Stars - as well as everyone that had the courage to submit and present a talk this year!
For the top sessions at JavaOne 2013, Oracle worked with Parleys to capture the audio and synch it with the presentations. They published them in a JavaOne 2013 Channel and my presentations were included. Without further ado, here they are for your viewing pleasure.
If you happen to watch these and have any feedback, please leave a comment or send a tweet to @mraible.
I flew into San Francisco this past Monday to speak at JavaOne 2013, and to meet with my new client. I made sure to wear a Broncos shirt since I was riding the train through Oakland and had some co-workers that were Raiders fans. My trip started off nicely as the Broncos dismantled the Raiders on Monday Night Football. My new team and I watched it during a team dinner at Havana in Walnut Creek. Historically, the Broncos and Raiders have had a heated rivalry historically, so the win was the perfect start to the week.
On Tuesday, I worked from my hotel in the morning, then met James Ward to do some last minute prep for our smackdown. The prior week, we both upgraded our respective apps to use the latest versions of Grails and Play Framework. I ran into afewissues when upgrading, while Play required some API changes.
We both added Memcachier to our apps (to share caching between dynos) and ran some Apache Bench tests. The results showed quite a bit of slowdown compared to last time, which we attributed to caching needing to make network hops. Other than that, we both had to make changes to our framework's buildpacks to get the latest versions running on Heroku, and when we headed for our talk, my instance of Grails wasn't running (60 second boot timeout on startup). The good news is it somehow solved its issues during our talk and was up and running when I checked it after, as it is now. Below is an embedded version of the presentation we delivered. You can also click here to see it in a new window, or view it on SlideShare.
On Wednesday morning, I tried to attend Venkat's Programming with Lambda Expressions in Java, but quickly discovered it was sold out. My talk on The Modern Java Web Developer started shortly after and I had a fantastic time talking to a packed room and preaching the virtues of learning and staying up-to-date with web technologies. I made sure to include a slide on Avatar, an Oracle-sponsored JavaScript-based framework that requires "very minor JavaScript knowledge". You can view my presentation below or on SlideShare.
After completing my talks, I journeyed to my client and practiced what I preached, successfully finishing a spike that reduced page load time from 8 seconds to 2 seconds. That evening, I attended the Oracle Appreciation Event at Treasure Island, had some cold beer and listened to some loud music.
I had a great time speaking at JavaOne this year, and look forward to my next speaking engagement. In November, I'll be traveling to Devoxx where I'll be giving a 3-hour University session on The Modern Java Web Developer. Hope to see you there!
I've been to JavaOne many times in my life, starting in 2004 and continuing in 2005, 2006 and 2008. I have fond memories of the first couple years, meeting all the Java open source guys and having a lot of fun.
You might notice that the aforementioned blog posts no longer show pictures. That's because they were originally hosted on Apple's HomePage, which they shut down years ago. I haven't bothered to republish the photos and fix the links, but I do still have them. For those looking for a blast from the past, checkout Mike, Howard and James or Bruce and Marc. I also have a set of photos from our Geronimo Live party in 2006.
As many of you know, JavaOne used to be a huge conference, attracting 15,000 attendees back in the day. Numbers have dwindled a lot since Oracle bought Sun and I've heard recent years are more around 1500. Since I've spoken at a lot of conferences, but never JavaOne, I figured I'd try this year. The good news is I got accepted and I'll be there next week!
This week, my lovely fiancé and I traveled to the City of Light. Our journey was designed around some speaking engagements at Devoxx France. Devoxx is one of my favorite conference franchises and Devoxx France has been special to me ever since the Devoxx (Belgium) I spoke at in 2011.
2011 was the year I spoke about my experience with Play, Scala, CoffeeScript and Jade. I wrote the presentation on my flight over, composed the demo video the night before and made it all happen in the nick of time. Of course, this was after 120 hours of research and preparation, so the presentation composition process had all the data I needed. You can imagine my sense of relief after pulling off that talk and getting an enthusiastic applause from the audience for my efforts.
One of the first audience questions I received was from Nicolas Martignole, asking if I'd speak at Devoxx France the following year. I whole-heartedly agreed to do it and was excited for the opportunity. It was with great disappointment that I later found out I couldn't attend Devoxx France in 2012. My client didn't like me taking so much time off and I agreed to scale my two week vacation back to 1 week. This year, I was determined to go, so I submitted some of my favorite talks: Comparing JVM Web Frameworks and The Play vs. Grails Smackdown with James Ward. I was extremely pleased when they both got accepted.
Side Story: I met Martin Odersky shortly when he sat down next to me for the Java Posse presentation in Belgium in 2011. After shaking his hand and introducing myself, I had to politely ask him to leave because it was Trish's seat. Talk about awkward; but Martin was very gracious and promptly found a new seat close by.
Comparing JVM Web Frameworks
Both talks required a bit of updating. For Comparing JVM Web Frameworks, I started reading The Paradox of Choice and found many parallels to the agony that developers experience with choosing a web framework. I described how I didn't think good framework decisions were based on the many, many features that frameworks have, but often on pre-defined constraints. There's those lucky developers that get to choose a Full Stack Framework because they're doing greenfield development. Then there's those that want a better Pure Web Framework that replaces something (e.g. Struts) that's not satisfying their needs. And lastly, there's those that've found it possible to leverage a SOFEA and use a JavaScript MVC framework with an API Framework on the backend. I don't think it makes sense to compare all web frameworks and I tried to use these pre-defined constraints (language, platform and application type) argument to separate into categories and help make choosing easier.
I took out the parts of the presentation that've pissed people off in the past - particular the JSF bashing by James Gosling, the Rails gushing from Craig McClanahan and the Pros and Cons sections of each framework. I added the history of web frameworks and research from InfoQ and devrates.com.
The best part of the JVM Web Frameworks talk was the audience's reaction and enthusiasm. Devoxx always seems to attract passionate developers and Devoxx France was no different. Developers packing the room, clapping after your intro, laughing at your jokes, signifying that they agree with you about JSF. As a speaker, it's an unbelievable experience.
You can view my Comparing JVM Web Frameworks presentation below or on Slideshare.net.
Play Frameworks vs. Grails Smackdown
To prepare for James Ward and my Play vs. Grails Smackdown, we had a number of goals. First of all, we wanted to update our apps to use the latest versions of each framework. I documented what it took for Grails, James just checked in his code to GitHub. It was interesting to see that Grails 2.0.3 -> 2.2.1 caused a number of issues with testing, while Play 2.0.3 -> Play 2.1.0 required API changes, but nothing for tests. Secondly, we updated all the stats for our pretty graphs and ran load tests again.
This is where the fun started. On Tuesday evening, I decided to challenge the notion that Play was twice as fast as Grails. James had proven this with Apache Bench tests. With Play 2.0 and Grails 2.0 (last summer), we clocked Play at 251/requests per second and 198 for Grails. After upgrading each app to the latest releases, we found the numbers to be 233/second for Play and 118 for Grails.
However, Apache Bench only tests until the first byte is received. Since I've done a lot of browser optimizations recently, I fired up whichloadsfaster.com, captured a screenshot and added it to our presentation. The next day, James added a CDN and a bunch of caching to his app and re-ran his AB tests.
Now he was smoking Grails, so I added a CDN and caching as well. However, the best I could do was just over 1000/requests per second, while he was around 2200/second. When he ran live tests during our talk, Play was around 2800/sec and Grails was around 900.
It was great to see how much better performance we could get with caching and a CDN. The best part is this should be available to most applications, not just these frameworks. By adding a CDN (we used Amazon CloudFront) and caching, we were both able to 10x the performance of our apps. You can find our presentation here or view it below.
Summary
This was a very enjoyable conference to attend as a speaker. First of all, it was in one of the most beautiful cities in the world, but it's also a very special place for Trish and I. We got engaged just outside of Paris in Versailles after the last Devoxx conference I spoke at. Trish has some amazing photos from that trip. Secondly, the Devoxx conference attracts a special kind of developer - one that is passionate about and eager for knowledge. Lastly, speaking with my good friend James, in an exotic city about something we love - that was special. Asking for beers and having them brought to us at the start of our Smackdown. That was magical (thanks Nicolas!).
To all the Devoxx organizers and crew - well done on a great show!
In preparation for my Grails vs. Play Smackdown at Devoxx France next week, I recently upgraded my Grails version of Happy Trails from Grails 2.0.3 to Grails 2.2.1. I ran into a few issues along the way and figured I'd document them here to help others out.
Fixing the source The first issue I ran into was Spock and Groovy 2 incompatibilities.
| Resolving plugin JAR dependencies
| Error WARNING: Dependencies cannot be resolved for plugin [mail] due to error: startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/Users/mraible/.grails/ivy-cache/org.spockframework/spock-core/jars/spock-core-0.7-groovy-1.8.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 0.7.0-groovy-1.8 is not compatible with Groovy 2.0.7. For more information, see http://versioninfo.spockframework.org
I posted the problem to StackOverflow and got a response almost immediately. While this pull request helped me quite a bit, it was ultimately caused by my vision: I had two "geb-spock" dependencies listed in BuildConfig.groovy with different groupIds.
At this point, I also moved all my plugin dependencies from application.properties to BuildConfig.groovy.
The next problem I ran into was a unit test and functional tests failing. The unit testing issue was caused by my Direction model not being in the tests @Mock annotation. After I added it, validation kicked and I recognized my test was invalid. I added @Ignore and continued.
The functional test seemed to be seemed to be caused by Geb and it trying to use the Chrome Driver. One of my tests didn't work with the default HtmlUnitDriver, so I used the ChromeDriver for the one test.
| Running 11 spock tests... 6 of 11
| Failure: signup as a new user(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.WebDriverException: Unable to either launch or connect to Chrome. Please check that ChromeDriver is up-to-date. Using Chrome binary at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.66 seconds
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.2', java.version: '1.7.0_04'
Driver info: org.openqa.selenium.chrome.ChromeDriver
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:111)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:115)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:161)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:107)
at happytrails.AuthenticatedUserSpec.signup as a new user(AuthenticatedUserSpec.groovy:25)
Even when running "grails -Dgeb.env=chrome test-app", this still happened. This was caused by the fact that I had GebConfig.groovy in test/functional/happytrails. Move it to test/functional solved the problem. I also discovered that I know longer needed Chrome to get this test to pass. Apparently, the HtmlUnitDriver has issues with Grails 2.2, but it seems to work for me.
After getting the Geb configuration fixed, I ran into a functional test failure:
| Running 11 spock tests... 5 of 11
| Failure: click signup link(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.ElementNotVisibleException: Element must be displayed to click (WARNING: The server did not provide any stacktrace information)
Even though I could see the "signup" link when I ran "grails run-app", I could see that it didn't show up when running tests in Chrome. This turned out to be caused by an extraneous <div class="nav-collapse"> I had in my main.gsp. Removing it solved the problem. It's strange that this never showed up with Grails 2.0. My only guess is that Geb someone didn't look at the visibility of the element.
The last testing-related issue I ran into was a InvalidElementStateException:
| Running 11 spock tests... 7 of 11
| Failure: add new route to region(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.InvalidElementStateException: Element must be user-editable in order to clear it. (WARNING: The server did not provide any stacktrace information)
I was able to fix this by changing AddRoutePage.groovy from:
And then referencing name, distance and location accordingly (form.name, etc.) in AuthenticatedUserSpec.groovy.
CloudBees
After I had everything working locally, I logged into Jenkins on CloudBees. Since I hadn't used it in a while, I had to wait a bit while my Jenkins server was re-commissioned. Once it was up, I tried to select Grails 2.2.1 to build with, but found it wasn't available. After a tweeting this, I learned about Grails Wrapper, found that the latest Grails Jenkins plugin supported it and got everything working. I later discovered that CloudBees does support Grails 2.2.1, I just needed to setup another Grails installation to automatically download and install 2.2.1.
Heroku
The last two issues I ran into were with Heroku. Since I was upgrading everything, I wanted Grails to build/run under Java 7 and use Servlet 3. I changed the appropriate properties in BuildConfig.groovy, configured Heroku and deployed. No dice.
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.
Play and Grails have been hyped as the most productive JVM Web Frameworks for the last couple of years. That hype has recently grown thanks to both frameworks' 2.0 releases. That's why James Ward and I decided to do a presentation at ÜberConf comparing the two. In April, we proposed the talk to Jay Zimmerman, got accepted and went to work.
How we did it
In the beginning of May, we met at a brewery in LoDo and sketched out the app we wanted to build. We also came up with a schedule for development and a plan for the presentation. We decided to build two different webapps, each with little-to-no Ajax functionality and a few features that we could use to load test and compare the applications.
We started out with the name “Happy Trails” since we both liked trails and happy hours. Later, James found that www.ubertracks.com was available and purchased the domain. We setup the Grails app to be on bike.ubertracks.com and Play/Java to be on hike.ubertracks.com. We managed our source code on GitHub, continuously tested on CloudBees and deployed to Heroku. Two weeks ago, when we were finishing up our apps, we hired a friend (Linsay Shirley) to do QA.
After fixing bugs, I emailed Patrick Lightbody, got some “cloud dollars” for Neustar Web Performance and started running load tests. The Wednesday before last, at 2 in the morning, I recorded a simple browsing regions and routes script and set it to go to 50 users over a 5 minute period and then sustain 50 for another 5 minutes. It was fun to watch the log messages whiz through my console so fast they got blurry. About halfway through testing the Grails app, there was an OOM issue, but it eventually recovered. Limiting db connections to 4 and scaling to 5 Dynos in future tests helped alleviate any issues.
What we found
We arrived at a number of conclusions after doing our research:
Code
From a code perspective, Play 2 and Grails 2 are very similar frameworks.
Code authoring was good in both, but lacking IDE support for Play 2's Scala Templates.
Grails Plugin Ecosystem is excellent.
TDD-Style Development is easy with both.
Type-safety in Play 2 was really useful, especially routes.
Statistical Analysis
Grails has better support for FEO (YSlow, PageSpeed)
Grails has less LOC! (6 lines less, but 40% more files)
1 Dyno - Grails had 2x transactions!
Grails experienced OOM about halfway through.
Apache Benchmark with 10K requests:
Play: ~10% failed requests, Grails: 0
Requests per second: {Play: 170, Grails: 198}
Requests per second: {Play: 251, Grails: 198}
Load Test with 100 Real Users:
Grails: 10% more transactions, 0 errors
Ecosystem Analysis
"Play" is difficult to search for.
Grails is more mature.
Play has momentum issues.
LinkedIn: more people know Grails than Spring MVC.
Play has 3x user mailing list traffic.
We had similar experiences with documentation and questions.
Outdated documentation is a problem for both.
Play has way more hype!
We figured we spent around 100 hours developing the apps, gathering data and creating the presentation. The good news is it's all open source! This means you can clone the project on GitHub (Grails is in the grails2 branch, Play is in the play2_java branch) and help us improve it. The presentation is in the master branch in the preso directory.
All the data we gathered is open for debate and we’d love to tune our apps to handle more requests per second. In fact, we already had a contributor discover an issue and provide a fix for Play that increases its throughput from 170 req/second to 252 req/second!
Regardless of what the stats and pretty graphs say, we both enjoyed our experiences with Play 2 and Grails 2. If you haven't tried them yourself, we encourage you to do so.
Last Wednesday, Trish and I traveled to Las Vegas for TheServerSide Java Symposium 2011 conference. We had a free room from TechTarget, but opted to upgrade to a suite with a view over the Bellagio Fountains. Trish won a trip to Vegas as a sales award earlier in the year and cleverly exchanged it for cash, so our upgrade was sort of free.
My first talk was on Online Video and my experience at Time Warner Cable. With my former team's iPad app releasing the day before, it was a fun session. The attendance was kind of sparse, but I had some good competition so wasn't surprised.
After I finished speaking, we headed to happy hour and met up with some friends that happened to be in town. We had dinner at the Todd English Pub and headed to the Penn & Teller show at the Rio. We closed the night after Trish had a 45-minute roll at the craps table at O'Sheas.
We slept in on Thursday and I gave my Comparing JVM Web Frameworks talk that afternoon. I made sure to mention some other methods to choosing web frameworks: doing performance comparisons like Peter Thomas has done or choosing Lift because one of its developers says it's the best. While Vaadin did sneak into the #5 spot, I made sure and mentioned that Wicket and Tapestry seem to belong there moreso (based on stats, mailing list traffic, etc.).
Trish took a bunch of pictures during my talk, which had a great turnout and lots of participation.
That evening, we celebrated St. Patty's Day with some college buddies of mine, ate great sushi at Mizuya and experienced the joys of three card poker. Thanks to TechTarget for inviting me to TSSJS 2011; we had an awesome time. You can find all the pictures we took on Flickr.
I expected this, as I certainly don't know every framework as well as I'd like. The mistake I made was asking for the community to provide feedback on my ratings without describing how I arrived at them. From Peter Thomas's blog:
What you are doing is adjusting ratings based on who in the community shouts the loudest. I can't help saying that this approach comes across as highly arrogant and condescending, you seem to expect framework developers and proponents to rush over and fawn over you to get better ratings, like waiters in a restaurant trying to impress a food-critic for Michelin stars.
I apologize for giving this impression. It certainly wasn't my intent. By having simple numbers (1.0 == framework does well, 0.5 == framework is OK and 0 == framework not good at criteria) with no rationalization, I can see how the matrix can be interpreted as useless (or to put it bluntly, as something you should wipe your ass with). I don't blame folks for getting angry.
For my Rich Web Experience presentation, I documented why I gave each framework the rating I did. Hopefully this will allow folks to critique my ratings more constructively and I can make the numbers more accurate. You can view this document below or on Google Docs.
In the end, what I was hoping to do with this matrix was to simply highlight a technique for choosing a web framework. Furthermore, I think adding a "weight" to each criteria is important because things like books often aren't as important as REST support. To show how this might be done, I added a second sheet to the matrix and made up some weighting numbers. I'd expect anyone that wants to use this to downloaded the matrix, verify the ratings are accurate for your beliefs and weight the criteria accordingly.
Of course, as I and many others have said, the best way to choose a web framework is to try them yourself. I emphasized this at the end of my presentation with the following two slides.