Planet Apache

Syndicate content
Updated: 4 hours 17 min ago

Gianugo Rabellino: So where have I been?

Thu, 2015-02-05 15:21

TL;DR – here:

Have open source, will travel. And travel more than what the map shows, as I have been multiple times in many of those countries.

Thing is, I haven’t stayed long. With the exception of China, where I usually stay for a whole week, I try to jam-pack as much as I can in my travels, and that usually means I’m in a country for an average of 36 hours before I move on. The craziest ones are the “three strikes” days: wake up early in country #1, fly to country #2, fly out in the late evening and sleepcrash in country #3. My back still holds a grudge for doing Sweden, Finland and Portugal this way.

As counterintuitive as it may seem, this travel pattern while positively crazy is incredibly productive. While I started to travel this way so that I could minimize time away from my family, I quickly understood it helps immensely to focus and get things done effectively. It does take a toll on planning, but there is a whole lot of things you can do in one day: my daily fare typically includes at least a few internal meetings, a couple of customer/partner visits, the occasional press roundtable and a talk at a community event.

It is frantic indeed, and sightseeing is pretty much out of the question unless it’s a drive-by on the road to or from a meeting. I do however spend lots of time with local colleagues, and that alone helps a lot understanding the place I’m visiting: many tourists may spend weeks in the same place, visit every corner, and yet fail to understand what a country is all about as they lack contact with local people. Me, I will forever cherish the two hours I spent last Monday with 40 students from Egypt, learning so many things about their country.

Another great way to learn about a foreign place is food. It takes some convincing, especially in far away countries, to talk colleagues into ditching the typical 5-star hotel international buffet for a local dive place, but it invariably pays off. I have very fond memories of a Padang place in Indonesia, and I will positively refuse to leave Singapore without a pilgrimage to the Maxwell Road hawker stalls. During this very last trip I discovered Ful Medames and Mulukhiiyah, and I am invariably looking forward to what China will have to offer in my next trip. For the germophobics reading this, know that in four years I have only been sick once, and that was when I couldn’t bail from a lunch at an Italian place in Beijing.

Then again, being with local people makes all the difference. And having a job where I get to meet so many local communities takes all the wear of travel away. I am sitting in my last hotel room in South Africa as I write this: I landed at 5.30am, gave an opening speech at an open source event at 9am, rushed to the office for a PR roundtable, shot a video and had a few internal sync meetings. As I try to pick myself up for my last day on the road, and then finally go back to my family I can’t help but thinking how lucky I am.

Categories: FLOSS Project Planets

Matt Raible: Best Practices for using Foundation with AngularJS

Thu, 2015-02-05 11:21

I was recently tasked with doing some research to figure out the best way to use Foundation with AngularJS. Goals for this research included:

  1. Identify use cases of Foundation for Sites vs Foundation for Apps and recommend when to use each.
  2. Look at pros and cons of using AngularJS with Foundation for Sites.

I'm writing this blog post to get feedback from you, fellow web developers, on your experience with Foundation. Have you tried using Foundation for Sites with AngularJS? If so, did you experience any pain?

From what I can tell, it looks like Foundation for Apps (FA) was created because folks had issues making AngularJS and Foundation 5 play nicely together. The Next Foundation explains why FA was created. Reddit's web_design zone has quite a few comments related to this article.

From there, I found a few ZURB blog posts that describe FA's three main advantages over Foundation for Sites (FS):

  1. A New Grid
  2. Motion UI
  3. AngularJS Integration

This thread on the Foundation forums seems to indicate that FA would be good for developing applications while FS would be good for an intranet built on WordPress (since it's more of a website than a webapp).

Foundation for apps is for making responsive web apps vs responsive web sites. The difference is in the structure of an app. They usually take up the screen and instead of the page scrolling, content in the app scrolls. Apps employ stateful views, so a view can change without reloading the app, creating a better user experience.

This other thread backs up that notion.

Foundation for Apps will be an additional version of Foundation - not a replacement.

This means Foundation for Sites will continue on along side the new Apps version. Ink will be Foundation for Emails.

Having said that, choosing which one to use simply depends on the type of site you need to build. The Apps grid is better suited to make web apps or apps that can be wrapped for native.

The syntax is different (on purpose) and we are taking great care to make it easy to get.

You should continue using Foundation for sites as long as you need traditional scrolling websites. We don't expect people to convert an existing site to an app unless they need to re-do their site anyways.

I also found Angular Foundation which is a "a port of the AngularUI team's excellent angular-bootstrap project for use in the Foundation framework".

The problem I see with using Angular Foundation over Foundation for Apps is that it's maintained by folks that aren't developing Foundation. It's more of a "here's some Bootstrap widgets as Foundation widgets".

It could also come down to IE support. Angular Foundation supports IE9+ while Foundation for Apps is IE10+. From What You Need To Know About Zurb Foundation for Apps:

Foundation for Apps works with all of the modern browsers including Internet Explorer 10. It doesn't support IE9 and other older browsers because of the new CSS3 features and issues of AngularJS in older browsers. Below is the snapshot of the compatibility list grabbed from Zurb website.

I wrote this article in order to publish my research findings about Foundation for Apps vs. Foundation for Sites. It seems like the natural thing to do is to use FA for any webapps we create and FS for any websites (e.g. WordPress sites). Do you agree with these findings? Any other recommended practices for integrating Foundation with AngularJS?

Sidenote: For the project I'm working on, we haven't chose a backend framework yet. We've chosen Heroku as our deployment platform, so there's a plethora of languages and frameworks to choose from. It's too bad JHipster doesn't support Foundation. I could probably sell the team on Java + Spring Boot pretty easily if it did.

Categories: FLOSS Project Planets

Francesco Chicchiricco: Maven notifications under KDE

Thu, 2015-02-05 10:10
Empowering KDE notifications for our beloved Maven builds.
Categories: FLOSS Project Planets

Matt Raible: The Art of AngularJS in 2015

Wed, 2015-02-04 11:17

I've been tracking statistics on jobs and skills for JavaScript MVC frameworks ever since I Compared JVM Web Frameworks at Devoxx France in 2013. At that time, Backbone was the dominant framework.

Last year, I updated those statistics for a presentation on AngularJS at Denver's Derailed. Angular had a similar amount of jobs as Backbone and a lot of people added it to their LinkedIn profiles. I found that Ember had grown around 300%, Backbone 200% and Angular 1000%!

Before presenting on AngularJS at last night's Denver Open Source Users Group, I updated these statistics once again. The charts below show how the number of jobs for Angular has doubled in the last year, while jobs for Ember and Backbone have fallen slightly. As far as skills, developers learning Ember and Backbone has increased 200%, while skilled Angular folks has risen 400%.

Yes, AngularJS has experienced huge growth in the last couple of years. You might even say it's the Struts of the JavaScript world. I like to say that Struts 1.x was the 'Killer App' for J2EE back in the day.

For the presentation I delivered last night, I made a number of improvements over last year's. I added a live coding demo based on my Getting Started with AngularJS tutorial. I used IntelliJ's live templates to make it look easy. However, since the audience was quiet, and some were falling asleep, I skipped over the testing demo.

I added a few slides on Foundation for Apps (FA). We've selected AngularJS and Foundation on my current project, and I've been researching how to integrate the two lately. FA is one solution I've found, Angular Foundation is another. If you know of others, please let me know.

For Java developers getting started with Angular, I recommended JHipster. I talked about its foundational frameworks and project options when creating your project. I included screenshots of its slick metrics UI and code generation features.

I also added a slide for Dave Syer's excellent five-part series on Spring and AngularJS:

Finally, I added a number of slides on Angular 2.0. I encouraged folks to checkout The Twelve-Factor App and James Ward's Java Doesn’t Suck – You’re Just Using it Wrong.

The discussion with the audience was great, particularly around HTTP/2 and minification/concatenation of assets. Thanks to all who attended, I really enjoyed having the opportunity to share what I've learned.

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

If you live in Denver, there's a number of interesting meetups happening in the next couple months.

I'm also looking for speakers to teach programming to kids at Devoxx4Kids Denver. Let me know if you have a fun topic you'd like to present.

Categories: FLOSS Project Planets

Bryan Pendleton: Wikipedia minutiae

Wed, 2015-02-04 10:03

There's a great article on Medium about Giraffedata: One Man’s Quest to Rid Wikipedia of Exactly One Grammatical Mistake.

Giraffedata—a 51-year-old software engineer named Bryan Henderson—is among the most prolific contributors, ranking in the top 1,000 most active editors. While some Wikipedia editors focus on adding content or vetting its accuracy, and others work to streamline the site’s grammar and style, generally few, if any, adopt Giraffedata’s approach to editing: an unrelenting, multi-year project to fix exactly one grammatical error.

What, precisely, is that grammatical issue? Giraffedata explains it on a personal Wikipedia page (I wasn't even aware there were such things): User:Giraffedata/comprised of

Many people do not accept "comprised of" as a valid English phrase for any meaning. The argument goes that "to comprise" means to include, as in "The 9th district comprises all of Centerville and parts of Easton and Weston." And thus, "the 9th district is comprised of ..." is gibberish.

The phrase apparently originated as a confusion of "comprise" and "composed of", which mean about the same thing, as in "the 9th district is composed of ..." There is a traditional saying to help people remember these two sound-alike words: "The whole comprises the parts; the parts compose the whole."

But "comprised of" is in common use and some people defend it as a fully valid additional definition of "to comprise". Even dictionaries acknowledge this usage, though they all tell you it's disputed and typically discourage writers from using it. See for example Wiktionary.

Here is my view of why "comprised of" is poor writing

As the Medium essay notes, Giraffedata's work isn't always welcomed.

He was surprised, however, to find in the first three months that some people disagreed with his edit, sometimes vehemently. “When the first few people said, ‘Why did you do this?’ I said, ‘Well, it’s not grammatical. It’s not English at all.’ And then finally somebody came and said, ‘You jerk, it’s a matter of opinion! It’s completely valid, I looked it up in my dictionary! You have no right to mess with my article!’” Henderson laughs. “That came as quite a surprise.” He stopped checking the ‘minor edit’ box, to acknowledge that some users might find the change controversial.

Indeed, he acknowledges the controversy on his personal Wikipedia page:

A usage note in the Merriam-Webster dictionary notes that a writer "may be subject to criticism" for using "comprised of" and suggests alternative wording for that reason. It notes that in spite of being in use for over a hundred years, it is still attacked as wrong, but says it isn't clear why the attackers have singled out this usage. Opposition has long been declining; in the 1960s, 53 percent of American Heritage Dictionary's expert Usage Panel found the wording unacceptable; in 1996, only 35 percent objected; by 2011, it had fallen a bit more, to 32 percent (quoted here). OED usage note calls it "part of standard English".

Still, doing this brings him joy:

When asked what motivates him, Henderson says he views his pursuit as similar to that of people who choose to spend their Saturdays picking up litter from the side of the road. “I really do think I’m doing a public service, but at the same time, I get something out of it myself. It’s hard to imagine doing it for the rest of my life,” he says with a laugh. “I don’t have any plans to quit, but I guess eventually, I’ll have to find a way. It’s hard to walk away, especially when I’ve actually accomplished something.”

I understand the compulsion, and I expect many have felt it; after all, Duty Calls.

Categories: FLOSS Project Planets

Bruce Snyder: Car vs. Bike in Boulder, Colorado :: Bruce Snyder's Status

Tue, 2015-02-03 22:24

On Thursday, April 24, 2014, I was in a very serious cycling accident in Boulder, Colorado while riding my new Cervélo S3 during the lunch hour and I am currently hospitalized in Denver, Colorado for at least the next 60 days. Damage ReportIn the wreckage, I suffered 11 fractured ribs (10 on the left side, most in multiple places, and one on the right), fractures of the L3 and L4 spinal vertebrae, one collapsed/punctured lung, one deflated lung, a nasty laceration on my left hip that required stitches and loads of road rash all over my back and left hip from being run over and rolled by the car. The worst part was being conscious through the entire ordeal, i.e., I knew I was being run over by a car.
Current Status After undergoing emergency spinal surgery involving the insertion of hardware including mounting hardware, rods and screws to create a fusion from the L2 - L5 vertebrae and cleaning out much debris from various spinal process fractures that punctured the spinal dura, I am now able to control everything from the knees up with the exception of my butt. I do feel my feet and I can distinguish sharp vs. dull touches in some areas but I am not able to flex my feet/ankles or wiggle my toes at this time. After the surgery, I was in the Intensive Care Unit (ICU) at Boulder Community Hospital for eight days. Since this time, I have been transferred to Craig Hospital in Denver, Colorado. Craig is a world-renowned hospital for it's spinal and brain injury rehabilitation programs.

(For those who are curious, I'm told that the bike was left almost untouched. But I will certainly have my family take it to Excel Sports in Boulder to be fully evaluated. )

A Very Special Thank You There is one guy who deserves a special thank you for his compassion for a stranger in distress. Gareth, your voice rescued me and got me through the initial accident and your clear thinking helped me more than you will ever know. After you visited me at the Boulder Hospital, I totally fell apart just because I heard your voice again. We will meet again, my brother. 
Also, a special thank you to Mike O. for introducing Gareth and I after the accident. Thanks, buddy. To My Family and Friends My wife Janene has truly been my rock through this entire ordeal. Never did she waver and, for me, the sun rises and sets with her. She and my girls have given me such strength when I needed it most. I am truly blessed with my family and friends.

My brother, Michael, was like a sentry -- by my side, from early morning until late into the night, supporting me in any way he could. I love you, Michael!

The moment my brother, my parents and my in-laws received the news of the accident, they packed their cars and hauled ass through the night 1000 miles to be by my side. I love you all so much and I could not have gotten this far without you. You are all amazing!

Thank you to my close friends for whom this experience only brought us closer. Karen, Dan, Anna, Sarah, and Sasha, I love you guys! Filip, you are very special to me and your dedication to visiting me and helping me keep my spirits high is stellar, thank you! Mike O., the chicken curry was delicious! Who knew this dude can cook *and* write code, thank you! Tim R., you have been my cycling buddy for a number of years and we were riding together the day of the accident just prior to its occurrence. You've stayed by me and met my family and helped in any way you can, thank you!

To all my friends and neighbors who immediately mobilized to provide my family with more delicious meals than they could possibly keep up with eating, you have really made us feel loved and watched over. Not only has Louisville, Colorado been ranked as one of the best places to live in the USA by Money Magazine for the last several years, the community of friends and neighbors is like an extended family -- you guys are the best!
Thank You To Everyone Thank you for all of your phone calls, emails, texts, tweets, concerns, hospital visits and well-wishes from everyone around the world. The level of compassion that I have experienced from near and far has been absolutely overwhelming for me. Please understand that I am not able to communicate directly with every single person simply due to the sheer volume of communications and the amount of time I am now spending doing rehab at Craig Hospital. I still get exhausted fairly easily doing rehab and just trying to live my life right now at Craig Hospital -- and this is coming from someone who could easily run 10 miles or ride 30+ miles at lunch just a couple weeks ago. This whole experience is absolutely flooding me emotionally and physically.

The Gory Details For those who want more details as the shit went down, please see the Caring Bridge :: Bruce Snyder website set up my extraordinary friend Jamie Hogan. This website is where Janene has been posting updates about my experience since the beginning. I will be adding my experiences henceforth here on my blog as I travel the winding road of recovery.

Conclusion Life is precious and I am so very happy to be alive.

And please, please do not ever text and drive. 
Categories: FLOSS Project Planets

Justin Mason: Links for 2015-02-03

Tue, 2015-02-03 18:58
Categories: FLOSS Project Planets

Colm O hEigeartaigh: New SAML validation changes in Apache WSS4J and CXF

Tue, 2015-02-03 12:27
Two new Apache WSS4J releases are currently under vote (1.6.18 and 2.0.3). These releases contain a number of changes in relation to validating SAML tokens. Apache CXF 2.7.15 and 3.0.4 will pick up these changes in WSS4J and enforce some additional constraints. This post will briefly cover what these new changes are.

1) Security constraints are now enforced on SAML Authn (Authentication) Statements

From the 1.6.18 and 2.0.3 WSS4J releases, security constraints are now enforced on SAML 2.0 AuthnStatements and SAML 1.1 AuthenticationStatements by default. What this means is that we check that:
  • The AuthnInstant/AuthenticationInstant is not "in the future", subject to a configured future TTL value (60 seconds by default).
  • The SessionNotOnOrAfter value for SAML 2.0 tokens is not stale / expired.
  • The Subject Locality (IP) address is either a valid IPv4 or IPv6 address.
2) Enforce constraints on SAML Assertion "IssueInstant" values

We now enforce that a SAML Assertion "IssueInstant" value is not "in the future", subject to the configured future TTL value (60 seconds by default). In addition, if there is no "NotOnOrAfter" Condition in the Assertion, we now enforce a TTL constraint on the IssueInstant of the Assertion. The default value for this is 30 minutes.

3) Add AudienceRestriction validation by default

The new WSS4J releases allow the ability to pass a list of Strings through to the SAML validation code, against which any AudienceRestriction address of the assertion are compared. If the list that is passed through is not empty, then at least one of the AudienceRestriction addresses in the assertion must be contained in the list. Apache CXF 3.0.4 and 2.7.15 will pass through the endpoint address and the service QName by default for validation (for JAX-WS endpoints). This is controlled by a new JAX-WS security property:
  • ws-security.validate.audience-restriction: If this is set to "true", then IF the SAML Token contains Audience Restriction URIs, one of them must match either the request URL or the Service QName. The default is "true" for CXF 3.0.x, and "false" for 2.7.x.
Categories: FLOSS Project Planets

Adrian Sutton: Mounting a Time Capsule Drive In Linux

Mon, 2015-02-02 22:25

Lots of articles out there that have almost the right solution here but nearly all of them miss one critical component, so for my future sanity, here’s what works for me:

sudo mount.cifs //timecapsule.local/Data/ /mnt/directory/ -o “pass=password,sec=ntlm”

If you don’t have zeroconf working in your Linux install you’ll have to use the time capsule’s IP instead of it’s .local name.  The “Data” part is the name of the disk you want to mount as shown in Airport Utility (make sure you escape any spaces with backslash.

Critically, you need to insist on NTLM authentication using the sec=ntlm option.  You may additionally want to specify file_mode, dir_mode and other standard mount options.

If you are using disk or device password based security you only need to specify the password, the username is ignored. However, if you’re using account based security you’ll need to also supply a user= option to specify the correct username.

Categories: FLOSS Project Planets

Bryan Pendleton: Risky business

Mon, 2015-02-02 20:39

Really, when you get right down to it, I don't know very much about football.

So take this for what it's worth (nothing).

But I just don't get why everybody is jumping on the bandwagon to label the Seahawks's last play call "risky" or "stupid".

As I recall, Jerry Rice scored, what, 40 touchdowns on slant passes from inside the 10 yard line?

And Rice probably made 5 times that many first downs on that play, and perhaps 10 times that many total "quick slant" receptions in his career.

That was a perfectly fine play call, even a good one.

Malcolm Butler just did something completely unexpected and amazing.

Which is why, even though I didn't really care about the game, nor who won, and barely even watched a game of football all year, I still really enjoyed almost all of yesterday's game.

Go Patriots, go Seahawks. Well played, and good entertainment, start to finish.

Categories: FLOSS Project Planets

Heshan Suriyaarachchi: Resolving EACCES error when using Angular with Yeoman

Mon, 2015-02-02 19:19
In one of my earlier posts, I discussed installing NodeJS, NPM and Yeoman. Although the setup was good to start off my initial work, it was not was giving me the following error when trying to install Angular generator. Following post describe how to resolve this error.


| | .------------------------------------------.
|--(o)--| | Update available: 1.4.5 (current: 1.3.3) |
`---------´ | Run npm install -g yo to update. |
( _´U`_ ) '------------------------------------------'
| ~ |
´ ` |° ´ Y `

? 'Allo Heshan! What would you like to do? Install a generator
? Search NPM for generators: angular
? Here's what I found. Install one? angular
npm ERR! Darwin 14.0.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "-g" "generator-angular"
npm ERR! node v0.10.33
npm ERR! npm v2.1.11
npm ERR! path /Users/heshans/.node/lib/node_modules/generator-angular/
npm ERR! code EACCES
npm ERR! errno 3

npm ERR! Error: EACCES, unlink '/Users/heshans/.node/lib/node_modules/generator-angular/'
npm ERR! { [Error: EACCES, unlink '/Users/heshans/.node/lib/node_modules/generator-angular/']
npm ERR! errno: 3,
npm ERR! code: 'EACCES',
npm ERR! path: '/Users/heshans/.node/lib/node_modules/generator-angular/' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! error rolling back Error: EACCES, unlink '/Users/heshans/.node/lib/node_modules/generator-angular/'
npm ERR! error rolling back { [Error: EACCES, unlink '/Users/heshans/.node/lib/node_modules/generator-angular/']
npm ERR! error rolling back errno: 3,
npm ERR! error rolling back code: 'EACCES',
npm ERR! error rolling back path: '/Users/heshans/.node/lib/node_modules/generator-angular/' }

npm ERR! Please include the following file with any support request:
npm ERR! /Users/heshans/Dev/projects/myYoApp/npm-debug.log

It was due to a permission error in my setup. I tried giving my user the permission to access those files but it still didn't resolve the issue. Then I decided to remove my existing NodeJS and NPM installations. Then I used the following script by isaacs with slight modifications. It worked like a charm. Then I was able to successfully install AngularJS generator to Yeoman.

PS : Also make sure that you have updated your PATH variable in your ~/.bash_profile file.
export PATH=$HOME/local/bin:~/.node/bin:$PATH
Categories: FLOSS Project Planets

Justin Mason: Links for 2015-02-02

Mon, 2015-02-02 18:58
  • A Quiet Defense of Patterns

    Marc Brooker: ‘When it comes to building working software in the long term, the emotional pursuit of craft is not as important as the human pursuit of teamwork, or the intellectual pursuit of correctness. Patterns is one of the most powerful ideas we have. The critics may be right that it devalues the craft, but we would all do well to remember that the craft of software is a means, not an end.’

    (tags: marc-brooker design-patterns coding software teamwork)

  • One Hundred Miles of Solitude

    Via Walter, the best description of the appeal of Minecraft I’ve read:

    Minecraft is exceptionally good at intrinsic narrative. It recognises, preserves and rewards everything you do. It presses you to play frontiersman. A Minecraft world ends up dotted with torchlit paths, menhirs, landmarks, emergency caches. Here’s the hole where you dug stone for your first house. Here’s the causeway you built from your spawn point to a handy woodland. Here’s the crater in the landscape where the exploding monster took out you and your wheatfield at once. And, of course, here’s your enormous castle above a waterfall. There’s no utility in building anything bigger than a hut, but the temptations of architecture are irresistible. Minecraft isn’t so much a world generator as a screenshot-generator and a war-story generator. This is what will get the game the bulk of its critical attention, and deservedly so. That’s why I want to call attention to the extrinsic narrative. It’s minimal, implicit,  accidental and very powerful. It’s this: you wake alone beside an endless sea in a pristine, infinite wilderness. The world is yours. You can literally sculpt mountains, with time and effort. You’ll die and be reborn on the beach where you woke first. You’ll walk across the world forever and never see another face. You can build a whole empire of roads and palaces and beacon towers, and the population of that empire will only ever be you. When you leave, your towers will stand empty forever. I haven’t seen that surfaced in a game before. It’s strong wine.

    (tags: minecraft narrative gaming games story)

  • Backstage Blog – Prometheus: Monitoring at SoundCloud – SoundCloud Developers

    whoa, this is pretty excellent. The major improvement over a graphite-based system would be the multi-dimensional tagging of metrics, which we currently have to do by simply expanding the graphite metric’s name to encompass all those dimensions and use searching at query time, inefficiently.

    (tags: monitoring soundcloud prometheus metrics service-metrics graphite alerting)

  • ‘Prometheus instrumentation library for JVM applications’

    Good example of a clean java OSS release, from Soundcloud. will be copying bits of this myself soon…

    (tags: prometheus java libraries oss github sonatype maven releases)

  • Google Java Style

    A good set of basic, controversy-free guidelines for clean java code style

    (tags: style java google coding guidelines formatting coding-standards)

  • A Brief History of NSA Backdoors

    from 1946 to present

    (tags: nsa security backdoors sigint actel dual_ec_drbg crypto-ag crypto)

  • Study: You Can’t Change an Anti-Vaxxer’s Mind

    According to a major new study in the journal ‘Pediatrics’, trying to [persuade anti-vaxxers to vaccinate] may actually make the problem worse. The paper tested the effectiveness of four separate pro-vaccine messages, three of which were based very closely on how the Centers for Disease Control and Prevention (CDC) itself talks about vaccines. The results can only be called grim: Not a single one of the messages was successful when it came to increasing parents’ professed intent to vaccinate their children. And in several cases the messages actually backfired, either increasing the ill-founded belief that vaccines cause autism or even, in one case, apparently reducing parents’ intent to vaccinate.

    (tags: vaccination health measles mmr autism facts via:mrneutron stupidity cdc papers vaccines)

  • Coining “Dysguria”

    “dysaguria” is the perfect noun, and “dysagurian” is the perfect adjective, to describe the eponymous company in Dave Eggers’ The Circle. It’s not in the same league as Orwell, or Huxley, or Bradbury, or Burgess. But it does raise very important questions about what could possibly go wrong if one company controlled all the world’s information. In the novel, the company operates according to the motto “all that happens must be known”; and one of its bosses, Eamon Bailey, encourages everywoman employee Mae Holland to live an always-on (clear, transparent) life according the maxims “secrets are lies”, “sharing is caring”, and “privacy is theft”. Eggers’s debts to dystopian fiction are apparent. But, whereas writers like Orwell, Huxley, Bradbury, and Burgess were concerned with totalitarian states, Eggers is concerned with a totalitarian company. However, the noun “dystopia” and the adjective “dystopian” – perfect though they are for the terror of military/security authoritarianism in 1984, or Brave new World, or Farenheit 451, or A Clockwork Orange – do not to my mind encapsulate the nightmare of industrial/corporate tyranny in The Circle. On the other hand, “dysaguria” as a noun and “dysagurian” as an adjective, in my view really do capture the essence of that “frightening company”.

    (tags: dysaguria dystopia future sf authoritarianism surveillance the-circle google facebook)

  • A NetHack bot ascends!

    Via negatendo: ‘I would like to share my excitement about the fact that after almost a year of development, an instance of my NetHack bot has finally managed to ascend a game for the first time without human interventions, wizard mode cheats or bones stuffing, and did so at the public server at’ The bot is written in Clojure. Apparently ‘pudding farming’ did the trick…

    (tags: clojure via:negatendo pudding-farming games nethack bots)

Categories: FLOSS Project Planets

Matt Raible: Testing AngularJS Applications

Mon, 2015-02-02 16:31

This article is the second in a series about learning AngularJS. It describes how to test a simple AngularJS application. In a previous article, Getting Started with AngularJS, I showed how to develop a simple search and edit feature.

What you'll learn

You'll learn to use Jasmine for unit testing controllers and Protractor for integration testing. Angular's documentation has a good developer's guide to unit testing if you'd like more information on testing and why it's important.

The best reason for writing tests is to automate your testing. Without tests, you'll likely be testing manually. This manual testing will take longer and longer as your codebase grows.

What you'll need
  • About 15-30 minutes
  • A favorite text editor or IDE. We recommend IntelliJ IDEA.
  • Git installed.
  • Node.js and NPM installed.
Get the tutorial project

Clone the angular-tutorial repository using git and install the dependencies.

git clone cd angular-tutorial npm install

If you haven't completed the Getting Started with AngularJS tutorial, you should peruse it so you understand how this application works. You can also simply start the app with "npm start" and view it in your browser at http://localhost:8000/app/.

Test the SearchController
  1. Create app/search/search_test.js and populate it with the basic test infrastructure. This code sets up a mock SearchService that has the first function we want to test: query(term). It uses $provide to override the default SearchService. Angular unit-test controllers - mocking service inside controller was a useful question on Stack Overflow for figuring out how to mock services in controllers.

    'use strict'; describe(' module', function() { var mockSearchService; beforeEach(module('', function($provide) { mockSearchService = {query: function(term) {}}; $provide.value("SearchService", mockSearchService); })); });
  2. Modify karma.conf.js (in the root directory) to add the search implementation and test.

    files : [ ... 'app/components/**/*.js', 'app/search/search.js', 'app/search/search_test.js', 'app/view*/**/*.js' ],
  3. Add the first test to search_test.js. This test verifies that setting a search term and executing the search() function will call the service and return results. You can see the results returned from the service are mocked with deferred.resolve(). The deferred.resolve() call is how to handle promises in unit tests.

    describe('search by term', function() { var scope, rootScope, controller, deferred; // setup the controller with dependencies. beforeEach(inject(function($rootScope, $controller, $q) { rootScope = $rootScope; scope = $rootScope.$new(); controller = $controller('SearchController', {$scope: scope, SearchService: mockSearchService }); deferred = $q.defer(); })); it('should search when a term is set and search() is called', function() { spyOn(mockSearchService, 'query').andReturn(deferred.promise); scope.term = 'M';; deferred.resolve({data: {name: "Peyton Manning"}}); rootScope.$apply(); expect(scope.searchResults).toEqual({name: "Peyton Manning"}); }); });

    Related: Introduction to Unit Test: Spies is a good introduction to using spies in unit tests.

  4. Run the following command on the command line to start the Karma test runner. You can leave this process running and new tests will be run automatically. You can change the mocked data and expectation to see your test fail.

    npm test Running Tests from IntelliJ IDEA
    See Running Unit Tests on Karma to learn how to run your tests from IntelliJ IDEA.
  5. Add a test to verify a search occurs automatically when the term is in the URL. Notice how the code structure had to change a bit to handle $routeParams.

    describe('search by term automatically', function() { var scope, rootScope, controller, location, deferred; beforeEach(inject(function($rootScope, $controller, $q) { rootScope = $rootScope; scope = $rootScope.$new(); // in this case, expectations need to be setup before controller is initialized var routeParams = {"term": "peyton"}; deferred = $q.defer(); spyOn(mockSearchService, 'query').andReturn(deferred.promise); deferred.resolve({data: {name: "Peyton Manning"}}); controller = $controller('SearchController', {$scope: scope, $routeParams: routeParams, SearchService: mockSearchService }); })); it('should search automatically when a term is on the URL', function() { rootScope.$apply(); expect(scope.searchResults).toEqual({name: "Peyton Manning"}); }); });
  6. Add a test to verify the EditController works as expected.

    describe('edit person', function() { var scope, rootScope, controller, location, deferred; beforeEach(inject(function($rootScope, $controller, $q) { rootScope = $rootScope; scope = $rootScope.$new(); // expectations need to be setup before controller is initialized var routeParams = {"id": "1"}; deferred = $q.defer(); spyOn(mockSearchService, 'fetch').andReturn(deferred.promise); deferred.resolve({data: {name: "Peyton Manning", address: {street: "12345 Blake Street", city: "Denver"}}}); controller = $controller('EditController', {$scope: scope, $routeParams: routeParams, SearchService: mockSearchService }); })); it('should fetch a single record', function() { rootScope.$apply(); expect("Peyton Manning"); expect(scope.person.address.street).toBe("12345 Blake Street"); }); });

    After adding this test, you'll likely see the following error in your terminal.

    Chrome 40.0.2214 (Mac OS X 10.10.2) module edit person should fetch a single record FAILED fetch() method does not exist TypeError: Cannot read property 'name' of undefined

    This happens because the mockSearchService does not have a fetch method defined. Modify the beforeEach() on line 7 to add this function.

    mockSearchService = {query: function(term) {}, fetch: function(id) {}};
Extra Credit

Create a test for saving a person. Here's a question on Stack Overflow that might help you verify the location after a save has been performed.

Test the Search Feature

To test if the application works end-to-end, you can write scenarios with Protractor. These are also known as integration tests, as they test the integration between all layers of your application.

To verify end-to-end tests work in the project before you begin, run the following command in one terminal window:

npm start

Then in another window, run the following to execute the tests:

npm run protractor
  1. Write your first integration test to verify you can navigate to /search and enter a search term to see results. Add the following to e2e-tests/scenarios.js:

    describe('search', function() { var searchTerm = element(by.model('term')); var searchButton = element('search')); beforeEach(function() { browser.get('index.html#/search'); }); it('should allow searching at /search', function() { searchTerm.sendKeys("M"); { expect(element.all(by.repeater('person in searchResults')).count()).toEqual(3); }); }); });

    The "searchTerm" variable represents the input field. The by.model() syntax binds to the "ng-model" attribute you defined in the HTML.

  2. Run "npm run protractor". This should fail with the following error.

    [launcher] Running 1 instances of WebDriver Selenium standalone server started at ...F Failures: 1) my app search should allow searching at /search Message: NoSuchElementError: No element found using locator:"search")
  3. To fix, you need to add an "id" attribute to the Search button in app/search/index.html.

    <form ng-submit="search()"> <input type="search" name="search" ng-model="term"> <button id="search">Search</button> </form>
  4. Run the tests again using "npm run protractor". They should all pass this time.
  5. Write another test to verify editing a user displays their information.

    describe('edit person', function() { var name = element(by.model('')); var street = element(by.model('person.address.street')); var city = element(by.model('')); beforeEach(function() { browser.get('index.html#/edit/1'); }); it('should allow viewing a person', function() { // getText() doesn't work with input elements, see the following for more information: // expect(name.getAttribute('value')).toEqual("Peyton Manning"); expect(street.getAttribute('value')).toEqual("1234 Main Street"); expect(city.getAttribute('value')).toEqual("Greenwood Village"); }); });

    Verify it works with "npm run protractor".

  6. Finally, write a test to verify you can save a person and their details are updated. Figuring out how to verify the URL after it changed was assisted by this issue.

    describe('save person', function() { var name = element(by.model('')); var save = element('save')); beforeEach(function() { browser.get('index.html#/edit/1'); }); it('should allow updating a name', function() { name.sendKeys(" Updated"); { // verify url set back to search results browser.driver.wait(function() { return browser.driver.getCurrentUrl().then(function(url) { expect(url).toContain('/search/Peyton%20Manning%20Updated'); return url; }); }); // verify one element matched this change expect(element.all(by.repeater('person in searchResults')).count()).toEqual(1); }); }); });
  7. When you run this test with "npm run protractor", it should fail because there's no element with id="save" in app/search/edit.html. Add it to the Save button in this file and try again. You should see something similar to the following:

    Finished in 4.478 seconds 6 tests, 9 assertions, 0 failures
Source Code

A completed project with this code in it is available on GitHub at on the testing branch.

There are two commits that make the changes for the two main steps in this tutorial:


I hope you've enjoyed this quick-and-easy tutorial on testing AngularJS applications. The first couple AngularJS applications I developed didn't have tests and required a lot of manual testing to verify their quality. After learning that testing AngularJS apps is pretty easy, I now do it on all my projects. Hopefully this tutorial motivates you to do do the same.

Categories: FLOSS Project Planets

Matt Raible: Getting Started with AngularJS

Mon, 2015-02-02 12:10

I was hired by my current client in November to help them choose a technology stack for developing modern web applications. In our first sprint, we decided to look at JavaScript MVC frameworks. I suggested AngularJS, Ember.js and React. Since most of the team was new to JavaScript MVC, I decided to create a tutorial for them. I tried to make it easy so they could learn how to write a simple web application with AngularJS. I thought others could benefit from this article as well, so I asked (and received) permission from my client to publish it here.

What you'll build

You'll build a simple web application with AngularJS. You'll also add search and edit features with mock data.

What you'll need
  • About 15-30 minutes
  • A favorite text editor or IDE. I recommend IntelliJ IDEA.
  • Git installed.
  • Node.js and NPM installed.
Create a simple web application
  1. Clone the angular-seed repository using git:

    git clone angular-tutorial cd angular-tutorial
  2. There are two kinds of dependencies in this project: tools and angular framework code. The tools help manage and test the application.

    The project has preconfigured npm to automatically run bower so you can simply do:

    npm install
Run the application

The project is configured with a simple development web server. The simplest way to start this server is:

npm start

Now browse to the app at http://localhost:8000/app/.

Add a search feature

To add a search feature, open the project in an IDE or your favorite text editor. For IntelliJ IDEA, use File > New Project > Static Web and point to the directory you cloned angular-seed to.

The Basics
  1. Create an app/search/index.html file with the following HTML:

    <form ng-submit="search()"> <input type="search" name="search" ng-model="term"> <button>Search</button> </form>
  2. Create app/search/search.js and define the routes (URLs) and controller for the search feature.

    angular.module('', ['ngRoute']) .config(['$routeProvider', function ($routeProvider) { $routeProvider .when('/search', { templateUrl: 'search/index.html', controller: 'SearchController' }) }]) .controller('SearchController', function () { console.log("In Search Controller..."); });
  3. Modify app/app.js and add the "" module you created above.

    angular.module('myApp', [ 'ngRoute', 'myApp.view1', 'myApp.view2', 'myApp.version', '' ])
  4. Modify app/index.html and add a link to the search.js file.

    <script src="view2/view2.js"></script> <script src="search/search.js"></script> <script src="components/version/version.js"></script>
  5. Refresh your browser and navigate to http://localhost:8000/app/#/search. You should see an input field and search button. You should also see a log message printed in your browser's console. In Chrome, you can view the console using View > Developer > JavaScript Console. You can make it easier to navigate to this page by adding a menu item in app/index.html.

    <ul class="menu"> <li><a href="#/view1">view1</a></li> <li><a href="#/view2">view2</a></li> <li><a href="#/search">search</a></li> </ul>

This section has shown you how to add a new controller and view to a basic AngularJS application. This was fairly simple to create. The next section shows you how to create a fake backend API.

The Backend

To get search results, you're going to create a SearchService that makes HTTP requests. These HTTP requests will be handled by a mock backend using some of Angular's built-in mocking tools. The backend implementation was created using AngularJS Backend-less Development Using a $httpBackend Mock.

  1. Add a SearchService to app/search/search.js. This is done in Angular using its Factory Recipe. Make sure to remove the semicolon from the .controller code block.

    .controller('SearchController', function () { console.log("In Search Controller..."); }) .factory('SearchService', function ($http) { var service = { query: function (term) { return $http.get('/search/' + term); } }; return service; });
  2. Inject the SearchService into the SearchController and use it to get results from the backend. The form in app/search/index.html calls the search() function. The "term" is defined by the input field in this page with ng-model="term".

    .controller('SearchController', function ($scope, SearchService) { $ = function () { console.log("Search term is: " + $scope.term); SearchService.query($scope.term).then(function (response) { $scope.searchResults =; }); }; })

    If you try to search for a "foo" term now, you'll see the following error in your console.

    Search term is: foo
    GET http://localhost:8000/search/foo 404 (Not Found)
  3. Create app/search/mock-api.js for the fake backend. Populate it with the following JavaScript.

    // We will be using backend-less development // $http uses $httpBackend to make its calls to the server // $resource uses $http, so it uses $httpBackend too // We will mock $httpBackend, capturing routes and returning data angular.module('myApp') .service('ServerDataModel', function ServerDataModel() { = [ { id: 1, name: "Peyton Manning", phone: "(303) 567-8910", address: { street: "1234 Main Street", city: "Greenwood Village", state: "CO", zip: "80111" } }, { id: 2, name: "Demaryius Thomas", phone: "(720) 213-9876", address: { street: "5555 Marion Street", city: "Denver", state: "CO", zip: "80202" } }, { id: 3, name: "Von Miller", phone: "(917) 323-2333", address: { street: "14 Mountain Way", city: "Vail", state: "CO", zip: "81657" } } ]; this.getData = function () { return; }; = function (term) { if (term == "" || term == "*") { return this.getData(); } // find the name that matches the term var list = $.grep(this.getData(), function (element, index) { term = term.toLowerCase(); return (; }); if (list.length === 0) { return []; } else { return list; } }; }) .run(function ($httpBackend, ServerDataModel) { $httpBackend.whenGET(/\/search\/\w+/).respond(function (method, url, data) { // parse the matching URL to pull out the term (/search/:term) var term = url.split('/')[2]; var results =; return [200, results, {Location: '/search/' + term}]; }); $httpBackend.whenGET(/search\/index.html/).passThrough(); $httpBackend.whenGET(/view/).passThrough(); });
  4. This file uses jQuery.grep(), so you'll need to install jQuery. Modify bower.json and add jQuery to the list of dependencies.

    "dependencies": { ... "html5-boilerplate": "~4.3.0", "jquery": "~1.10.x" }

    Stop the npm process, run "npm install" to download and install jQuery, then "npm start" again.

  5. Modify app/app.js and add a dependency on ngMockE2E.

    angular.module('myApp', ['ngMockE2E', 'ngRoute', ...
  6. Modify app/index.html to include references to jquery.js, angular-mocks.js and mock-api.js. 

    <script src="bower_components/angular-route/angular-route.js"></script> <script src="bower_components/angular-mocks/angular-mocks.js"></script> <script src="bower_components/jquery/jquery.js"></script> ... <script src="search/mock-api.js"></script> <script src="components/version/version.js"></script>
  7. Add the following HTML to app/search/index.html to display the search results.

    <div> <pre>{{ searchResults | json}}</pre> </div>

    After making this change, you should be able to search for "p", "d" or "v" and see results as JSON.

  8. To make the results more readable, change the above HTML to use a <table> and Angular's ng-repeat directive.

    <table ng-show="searchResults.length" style="width: 100%"> <thead> <tr> <th>Name</th> <th>Phone</th> <th>Address</th> </tr> </thead> <tbody> <tr ng-repeat="person in searchResults"> <td>{{}}</td> <td>{{}}</td> <td>{{person.address.street}}<br/> {{}}, {{person.address.state}} {{}} </td> </tr> </tbody> </table>

This section has shown you how to fetch and display search results. The next section builds on this and shows how to edit and save a record.

Add an Edit Feature
  1. Modify app/search/index.html to add a link for editing a person.

    <table ng-show="searchResults.length" style="width: 100%"> ... <tr ng-repeat="person in searchResults"> <td><a href="" ng-click="edit(person)">{{}}</a></td> ... </tr> </table>
  2. Add an edit() function to SearchController. Notice that the $location service dependency has been added to the controller's initialization function.

    .controller('SearchController', function ($scope, $location, SearchService) { ... $scope.edit = function (person) { $location.path("/edit/" +; } })
  3. Create a route to handle the edit URL in app/search/search.js.

    .config(['$routeProvider', function ($routeProvider) { $routeProvider .when('/search', { templateUrl: 'search/index.html', controller: 'SearchController' }) .when('/edit/:id', { templateUrl: 'search/edit.html', controller: 'EditController' }); }])
  4. Create app/search/edit.html to display an editable form. The HTML below shows how you can use HTML5's data attributes to have valid attributes instead of ng-*.

    <form ng-submit="save()"> <div> <label for="name">Name:</label> <input type="text" data-ng-model="" id="name"> </div> <div> <label for="phone">Phone:</label> <input type="text" data-ng-model="" id="phone"> </div> <fieldset> <legend>Address:</legend> <address style="margin-left: 50px"> <input type="text" data-ng-model="person.address.street"><br/> <input type="text" data-ng-model="">, <input type="text" data-ng-model="person.address.state" size="2"> <input type="text" data-ng-model="" size="5"> </address> </fieldset> <div> <button type="submit">Save</button> </div> </form>
  5. Modify SearchService to contain functions for finding a person by their id, and saving them.

    .factory('SearchService', function ($http) { var service = { query: function (term) { return $http.get('/search/' + term); }, fetch: function (id) { return $http.get('/edit/' + id); }, save: function(data) { return $'/edit/' +, data); } }; return service; });
  6. Create EditController in app/search/search.js. $routeParams is an Angular service that allows you to grab parameters from a URL.

    .controller('EditController', function ($scope, $location, $routeParams, SearchService) { SearchService.fetch($ (response) { $scope.person =; }); $ = function() {$scope.person).then(function(response) { $location.path("/search/" + $; }); } })
  7. At the bottom of app/search/mock-api.js, in its run() function, add the following:

    $httpBackend.whenGET(/\/search/).respond(function (method, url, data) { var results =""); return [200, results]; }); $httpBackend.whenGET(/\/edit\/\d+/).respond(function (method, url, data) { // parse the matching URL to pull out the id (/edit/:id) var id = url.split('/')[2]; var results = ServerDataModel.find(id); return [200, results, {Location: '/edit/' + id}]; }); $httpBackend.whenPOST(/\/edit\/\d+/).respond(function(method, url, data) { var params = angular.fromJson(data); // parse the matching URL to pull out the id (/edit/:id) var id = url.split('/')[2]; var person = ServerDataModel.update(id, params); return [201, person, { Location: '/edit/' + id }]; }); $httpBackend.whenGET(/search\/edit.html/).passThrough();
  8. Further up in the same file, add find() and update() methods to ServerDataModel.

    this.getData = function () { return; }; = function (term) { ... }; this.find = function (id) { // find the game that matches that id var list = $.grep(this.getData(), function (element, index) { return ( == id); }); if (list.length === 0) { return {}; } // even if list contains multiple items, just return first one return list[0]; }; this.update = function (id, dataItem) { // find the game that matches that id var people = this.getData(); var match = null; for (var i = 0; i < people.length; i++) { if (people[i].id == id) { match = people[i]; break; } } if (!angular.isObject(match)) { return {}; } angular.extend(match, dataItem); return match; };
  9. The <form> in app/search/edit.html calls a save() function to update a person's data. You already implemented this above. The function executes the logic below. 

    $location.path("/search/" + $;

    Since the SearchController doesn't execute a search automatically when you execute this URL, add the following logic to do so in app/search/search.js. Note that $routeParams is added to the list of injected dependencies.

    .controller('SearchController', function ($scope, $location, $routeParams, SearchService) { if ($routeParams.term) { SearchService.query($routeParams.term).then(function (response) { $scope.term = $routeParams.term; $scope.searchResults =; }); } ... })

    You'll also need to add a new route so search/term is recognized.

    .config(['$routeProvider', function ($routeProvider) { $routeProvider .when('/search', { templateUrl: 'search/index.html', controller: 'SearchController' }) .when('/search/:term', { templateUrl: 'search/index.html', controller: 'SearchController' }) ... }])
  10. After making all these changes, you should be able to refresh your browser and search/edit/update a person's information. If it works - nice job!
Source Code

A completed project with this code in it is available on GitHub at

There are three commits that make the changes for the three main steps in this tutorial:

Extra Credit

Deploy your completed app to Heroku. See running version of this tutorial at


I hope you've enjoyed this quick-and-easy tutorial on how to get started with AngularJS. In a future tutorial, I'll show you how to write unit tests and integration tests for this application. If you're in Denver next Tuesday, I'll be speaking about AngularJS at Denver's Open Source Users Group.

If you're a Java developer that's interested in developing with AngularJS and Spring Boot, you might want to checkout the recently released JHipster 2.0.

Categories: FLOSS Project Planets

Gianugo Rabellino: A tale of two countries

Mon, 2015-02-02 11:00

It boils down to shoes.

A lot of people asked me what it feels like to be an Italian in the USA. Books have been written, pictures have been taken and videos have been shot, so I feel I should spare you the details on getting Italian ingredients (you can get everything here), wrapping our heads about pounds and gallons (seriously, what were you guys thinking?) or remembering to have a full tank before hitting the outdoors (and a bear-proof food container if you plan to camp). Also, we are talking about a country that spans several time zones, so if there is no point trying to lump things up.

I do however have a story for you and I believe it pretty much sums up our experience in the Pacific Northwest, the corner of the States we have been lucky to dwell for the past four years.

A few months before leaving Italy, I needed new shoes. Nothing fancy, just an easy pair of loafers for the summer. I went to a shopping mall nearby, found what I wanted in a mid-level shoe store, paid up and off I was on my merry way. After a couple of days my new shoes split wide open, a tragic structural failure that had me limping home and later to the store to voice my disappointment.

They asked to see the receipt. They wondered if I did something weird with the shoes (though I don’t exactly look like I’m into parkour), they had me request to speak with the manager and finally they offered to repair, not reimburse – not replace, the offending shoe. They took their good time and after a few weeks I picked up a hack job of hot glue and amateur stitching that of course found its way to the trash bin shortly thereafter.

Fast forward a year or so, when I found another pair of loafers in a middle-of-the-road outlet store in North Bend. I liked them, tried them on, bought them and off I went. In a few weeks a small elastic band ripped off: it didn’t impair functionality, it was mostly cosmetic and a minor issue altogether. I didn’t bother going back to the store and actually kept that particular pair as my go-to shoes for quite a while. As a matter of fact, I still had those shoes on when I was back at the very same store almost a year later.

When the store clerk approached me, I told him I really liked the shoes I bought a year before, and I was wondering if they had something similar. He took a look at my feet and immediately asked what happened as he noticed the small rip in the fabric. I told him it was no biggie at all, but he insisted on seeing the shoe, asked when I bought it and told me in no uncertain terms that he was going to replace it under warranty. I told him I didn’t have the receipt, and he just asked for the credit card I used for the original transaction.

Minutes later I was driving home in my new free shoes, both me and my wife stunned at what just happened and commenting how good business sense, trust and, more generally, a positive attitude can make all the difference in the world. We love this place.

Categories: FLOSS Project Planets

Matt Raible: 2014 - A Year in Review

Mon, 2015-02-02 08:13

2014 was destined to be a spectacular year. When I wrote my thoughts down last January, I thought the Broncos would win the Super Bowl and my VW Bus restoration project would be finished by summer. To focus on finishing the bus project, I didn't submit any talks to conferences. Instead of traveling to exotic locations, we opted to visit a bunch in our own backyard instead.

I should've known it'd be an interesting year when the Broncos flopped in the Super Bowl.

For this Year in Review post, I'll use the format I've used the last couple of years.


I had three different clients throughout the year, all in the health care industry. I continued working on a project with John Muir Health where we developed a hybrid mobile app. I wrote about what I learned in Documenting your Spring API with Swagger and Developing an iOS Native App with Ionic. Since I wrote the article about Swagger's Spring MVC support, it has become much easier to integrate; now it only requires an @EnableSwagger annotation.

In April, I started consulting with a small company in Alabama. I helped them modernize their tech stack and implemented a number of web services with Apache Camel. I wrote about this in a four-part series in September and October.

  1. Developing Services with Apache Camel - Part I: The Inspiration
  2. Developing Services with Apache Camel - Part II: Creating and Testing Routes
  3. Developing Services with Apache Camel - Part III: Integrating Spring 4 and Spring Boot
  4. Developing Services with Apache Camel - Part IV: Load Testing and Monitoring

I continued leveraging Spring Boot in my client projects and wrote about Building a REST API with JAXB, Spring Boot and Spring Data at the end of that engagement.

In November, I had time off between clients. I visited my parents and their awesome retirement home in Montana. I also took some time to refactor AppFuse to be a bit leaner and meaner. I signed up with a new health care client in December. It's been an enjoyable experience so far, especially since I'm only working 20 hours per week this quarter.

I'm currently booked with clients through the end of March, but hoping to find one with a challenging project in April.


To optimize cash flow towards the bus project, I didn't submit any talks to conferences in 2014. However, I did talk about Comparing JVM Web Frameworks at the Denver Open Source Users Group and vJUG in February. I also spoke at local user groups (DeRailed and HTML5 Users) about The Art of AngularJS in the first part of the year. In the fall, I participated in panels on unit testing at Denver Startup Week and building a personal brand at AirConf.

I hope to attend and speak at more conferences in 2015. To help facilitate this, I've published a list of talks I'd like to present.

Devoxx4Kids Denver

2014 was the inaugural year for Devoxx4Kids Denver. In April, I announced our first meetup. It was an Introduction to Server-Side Minecraft Programming, taught by Denver's own Scott Davis. It was a wild success and the kids had a great time hacking.

I didn't plan any events during the summer, but we held a couple workshops in the fall: one on littleBits and a second on Greenfoot. The kids had a lot of fun with littleBits thanks to Juan Sanchez of Tack Mobile.

Unfortunately, I wasn't able to attend the Greenfoot workshop with Steve Pousty, but I heard it was awesome. Thanks again to Dan Allen for assisting with this class.

I haven't scheduled any Devoxx4Kids Denver meetups for 2015 yet. If you're interested in speaking, please let me know!


AppFuse: I didn't have many posts about AppFuse in 2014, but I did work on it from time to time. Upgrading its dependencies was a good way to stay up-to-date with open source frameworks, in addition to lots of reading. InfoQ covered the AppFuse 3.0 release and I continue to write for them.

In December, I removed 10,000 lines of XML from the project without affecting any functionality. In the past month, I've added support for generating CRUD for all its web frameworks (including AppFuse Light's). This includes Spring + FreeMarker, Stripes and Wicket. GWT support is still in progress. I hope to do a release soon; there's only 10 issues left as of this writing.

Roller: I didn't contribute any code to Apache Roller in 2014, but I upgraded this site to the latest release, upgraded to Java 8 + Tomcat 7, and integrated Wufoo Forms. I hope to make some scalability improvements to how I've deployed Roller in the near future.


I started off the year with a trip of a lifetime: Heli Skiing in British Columbia with CMH Gothics. An excerpt from my blog post:

Everyday was awesome, but Wednesday was incredible. It snowed 10 cm on Tuesday night, which turned into knee-deep powder and face shots. The hoots and hollers from everyone floating down forced my face into a sorta perma-grin. For many of us, it was the best skiing day of our entire lives. The video below tries to capture how much fun we had throughout the week, but ultimately fails. It's one of those things you have to experience to really appreciate. I ended up skiing around 80,000 vertical feet in four days.

After returning from British Columbia, Trish and I skied Breckenridge and Copper before taking the kids to Aspen for three feet of powder on Super Bowl weekend.

We skied all over Colorado in February and March. We even did some winter camping in the Syncro for Valentine's Day. It snowed a lot that night.

I wrote about all our skiing adventures in Farewell to the 2013-2014 Ski Season.

On April 10th, I reminisced that 10 years ago today, I bought a VW Bus. In that post, I explained some body-work quality issues the current restoration shop found. Nevertheless, I still thought it would be done in just a few more months.

We journeyed to Florida with Abbie and Jack for Spring Break. We relished in a super-fun family vacation where we golfed, swam and even spent a day frolicking with their Mom and fiancé (now husband), Dave. We're pretty proud that we're all still a family even though Julie and I are divorced. I wrote about our vacation in Spring Break in Florida: Golf, Beaches and Boats!

The hospitality from Trish's parents was like no other. I especially enjoyed a fishing trip with her Dad Joe in the Everglades. I love these people!

Our winter activities in the Syncro were incredible. Trish sold her Nissan Xterra (the one with the sick bass) in December. Yes, that's right - we only had one vehicle during ski season last year. The fact that it worked so well is amazing. In May, we kicked it up a knotch and drove it to Moab for Syncro Solstice. My parents went with us and we experienced fabulous weather and met a bunch of super-cool Vanagon owners.

We made record time from Moab back to Denver (5 hours). The next day is when things started to go downhill. I washed the engine for the VWs on the Green show. On that Monday, the engine started "lurching" where it seemed like it wasn't getting gas (it turned out to be caused by a lack of air). We drove the lurcher for several weeks, journeying to Campout for the Cause and a exhilarating raft trip down the Yampa River.

We had the lurching examined in mid-June by Rocky Mountain Westy; we also had them install some bumpers (for a better trailer hitch) and refreshed the tires.

The ol' van looked pretty good when our Dads arrived in Denver for some whitewater on the Arkansas.

In July, we skipped the annual road trip to The Cabin in favor of a romantic road trip to see old friends in Santa Fe. The Syncro's engine seized on that trip and I experienced my favorite breakdown ever. The engine froze at a gas station near our Ski Shack and I was able to walk home. Luckily, Trish's Dad had recently (over Father's Day weekend) gifted his Nissan Maxima to us. After a train ride to fetch our other car, our road trip continued and we celebrated our first anniversary at The Broadmoor.

After we returned from Santa Fe, I turned 40 years old. We rocked out a Journey concert to celebrate and Trish surprised me with a birthday visit from my kick-ass sister. The following evening, a bunch of friends took me on a Craft Brewery Tour in a school/prison bus. Both nights were epic.

At the end of July, Trish had one of her favorite photos featured on the cover of Whisky Magazine.

In August, we flew to Boston to celebrate Trish's Dad's 75th birthday. My parents joined us, we visited my Dad's family in New York and took the kids to the Big Apple. They loved the Statue of Liberty.

Abbie started middle school (6th grade) in mid-August and Jack started 4th grade. They looked great on their first day of school.

We were pumped about our new engine in the Syncro when we left Denver for Rafting the Green River through Desolation Canyon. We celebrated Jack's 10th birthday on that trip and had a very memorable expedition with some really cool people.

Trish's photo from our last night on the river makes me want do it all again.

In October, I started considering health over wealth when we embarked on a 21-day Sugar Detox. I'm proud to say that, as a result, I'm off blood pressure medication and continue to lose weight and feel better. We're cooking at home more than ever, exercising daily and I've lost almost 20 pounds in the process.

Medallion, the horse that Trish and Abbie were leasing (and almost ready to buy) got sick with colic on Friday, October 10. I remembered the day without looking at a calendar because Trish called me to tell me about his illness. She was out of town on a business trip and was absolutely distraught. She told me about the situation and asked me to visit Medallion while he endured extreme pain. I worked out of my van at the stables that day, checking on him every couple hours. They had to put him down that evening. Abbie took it pretty well when I told her a couple hours later, but there were heaps of tears later that night.

Our little girl turned 12 a few weeks later. The kids put on some dark costumes for Halloween.

A week later, I visited my parents in Montana. We played cribbage, ate scrumptious meals and trounced around the woods looking for bucks. I marveled at the beauty of my parents' retirement home.

I neglected to blog or tweet about my self-caused Syncro accidents in Q4 of 2014. Long story short: it's been getting body work done for quite some time (two accidents!) and I look forward to getting it back in tip-top-shape next week. Thank goodness for USAA insurance.

The biggest event of the year happened just before Christmas: THE BUS IS PAINTED!! HOLY CHRISTMAS PRESENT BATMAN!


It's hard to believe that 2015 could possibly top 2014. I started the year heli-skiing and ended it with a painted bus. However, the bus isn't done yet. Last year, I wrote:

My goal for 2014 is singular: finish The Bus.

I continue that mission this year. I've negotiated a deal with ReinCARnation to have it done by April 1st. Yes, it seems strange that April Fools is the finished bus delivery date. However, I'm confident they'll make it happen. This could be the year I've dreamed about since I was in high school. It was in 1991 that I first fantasized about putting a 911 engine in a VW Bus.

This year, I hope to be cruise around Colorado in two running VW Busses. From there, I plan to surround myself with the laughter of our children, the enthusiasm of our border collies and the warmness of Trish's love. It's gonna be a really great year!

Categories: FLOSS Project Planets

Claus Ibsen: Your Apache Camel applications now includes out of the box documentation

Mon, 2015-02-02 02:38
A couple of months back I blogged about the upcoming 2.15 release includes functionality to obtain fine grained information about each property configured on your endpoints in the blog titled - Apache Camel please explain me what these endpoint options mean.

We have continued on this path, and today we have extended this from endpoints to cover EIPs, data formats, and languages as well. In a nutshell almost all what you use and configure in your Camel applications now has the capability of including documentation out of the box at runtime. In addition all of those are associated with label(s) which we use as a way of categorizing them. So you can list all components for database, cloud, http, rest, messaging, etc etc.

As the EIPs is provided in the camel-core those all their options is fully documented, including details about their default values, if the option is required, whether an option is deprecated, and of course type information etc. The EIP itself is although currently only documented with a brief summary.

As Camel includes about 175 components then it will take some time to include documentation about each one of them. But we will setup in the build process of Apache Camel a report that outputs which components has missing documentation.

Okay a picture is worth a thousand words, so let me include a bit of eye candy of this in action using hawtio - the web console.

First an example of the EIP such as the aggregate EIP which has many options.

Showing properties of the Aggregate EIP in our Camel application,
including documentation out of the box Notice in the top there is checkboxes to:

  • show/hide documentation (the documentation is always provided as a tooltip)
  • show/hide default values (not in current screenshot, as just added)
  • show/hide unused values

And another screenshot showing the properties of the endpoints:

Showing properties of an endpoint in our Camel application,
including documentation out of the boxThis page is similar to the EIP page. It will also include the same checkboxes to filter.
Also notice those grey badges, they represent the label(s) this endpoint has been associated with. As we can see this is an endpoint from the core, and its scheduling.

All this information can be accessed at both runtime and design time. At runtime there is Java and JMX API from camel-core. And at design time the information is included in a new camel-catalog JAR that has json schema files for each EIP, component and so on. Likewise these json schema files can be retrieve at runtime using the Java and JMX API from camel-core as well.

So in other words this allows both end users and tooling to access this information.

For more information, read my previous blog, which I refer to in the top of this blog post.
What's NextWe have yet to implement a maven plugin as part of the build process of Apache Camel, that injects the EIP documentation in the XSD schema for the Spring and Blueprint XML DSL. When this is in place, then any IDE tooling should be able to leverage this, so while you edit those XML files, then the tooling can assist you and present the documentation etc.

Categories: FLOSS Project Planets

Nick Kew: Roots

Sun, 2015-02-01 20:51

I recently visited my father for a few days.

That doesn’t mean I revisited a childhood house, or even town: neither he nor I has done that for many years.  But one thing somehow took me back: hearing the cooing of pigeons outside.  That’s not even a very nice sound: it can be quite infuriating when it goes on incessantly, and I have some recollections of them being an annoying pest.  Yet that sound gave me a faintly Proustian nostalgia.  Followed of course by the realisation that there aren’t any around here, and faintly wondering why not: it can’t be just the neighbourhood cats!

During my visit I went to an event in London, and stayed on for a concert in the evening.  It was the RPO, at the Royal Festival Hall.  I got a great seat, and thoroughly enjoyed it.  But a little more than that: the orchestral sound was somehow ultimately “right”: the canonical orchestral sound.  What I was actually hearing (apart from a fine orchestra playing great music) was the Festival Hall’s acoustic, and I think that “rightness” must’ve been because that’s where I first ever heard an orchestra when my parents took me to see The Nutcracker there as a small child!

Hmmm ….

Categories: FLOSS Project Planets

Bryan Pendleton: Goodbye to January

Sun, 2015-02-01 12:19

Yesterday, it was 75 degrees in Marin County, clear blue skies, a gentle light wind, so we drove out to the Pt Reyes Lighthouse to see if we could see any Gray Whales. According to the recorded message at the Pt Reyes National Seashore Ranger Station, 18 whales had been seen on Friday.

Visiting the lighthouse to look for the whales in January is extremely popular, so at this time of year you can't drive all the way to the lighthouse. Instead, you have to park at Drake's Beach, and then take the shuttle bus, which is a nice ride and very comfortable.

There may be no better viewpoint over the Pacific Ocean than the observation deck above the Pt Reyes Lighthouse. With our binoculars, we could see miles out to sea, though the views got hazier as we looked. I'm pretty sure that we could see the Farallon Islands; it looked just like this.

But we didn't see any whales.

Sometimes that's what happens. I think they all were there on Friday.

So we rode the shuttle bus back to Drake's Beach, and went for a walk on the beach.

There were about a half dozen elephant seals sunning themselves on the beach, with docents keeping us tourists safely away. In many ways, seeing an elephant seal yawning, just 30 feet away, is a more impressive sight than a pod of gray whales 5 miles out to sea.

But they're both pretty great, and I'm glad we can make such a wonderful day trip on a Saturday in January. Yay California!

January was a month of glorious mild weather; I rode my bike to work every day, and barely needed my sweatshirt on many mornings.

But January was dry, reports the Merc: Driest January in history: Bay Area swings from boom to bust after wettest December.

For the first time ever, San Francisco, Oakland and Sacramento have recorded no rainfall for the month of January -- nada drop.


The state's monthly snowpack survey Thursday near Lake Tahoe's Echo Summit summed up the bad news: 12 percent of normal, with the equivalent of 2.3 inches of water content in the "meager" snowpack. Other spots around the state were worse, some slightly better -- but the outlook is equally dire.

"Unfortunately, today's manual snow survey makes it likely that California's drought will run through a fourth consecutive year," according to a news release from the Department of Water Resources.

Surprisingly, people don't seem to care. The winter snowpack's water content typically supplies about 30 percent of California's water needs and is considered water in the bank to melt through the dry summer months. Reservoirs rely on ample runoff from snowmelt to meet demand from summer through fall. After three years of drought and dwindling reservoir levels, the demand is growing.

And drought-weary Californians show signs of conservation fatigue. A poll from the Public Policy Institute of California, released this week, showed 59 percent of residents say the water supply is a big problem in their region, but that's down from 68 percent in October.

Indeed, you barely hear it discussed on the news, nobody seems to be talking about it at all.

There will be new data, though: A New Satellite Will Watch the Western Drought from Space.

SMAP will spend three years taking the most accurate readings ever of soil moisture around the world. That’s right: It will measure how wet the dirt is. From space.

As Bob Dylan says, though, you don't need a weatherman to know which way the wind blows. It is dry, dry, dry, and there are too many people in California using too much water, and nobody is working on ways to address the problem.

But it was a beautiful day to visit Pt Reyes yesterday.

Goodbye to January, happy February!

Categories: FLOSS Project Planets

Justin Mason: Links for 2015-01-31

Sat, 2015-01-31 18:58
Categories: FLOSS Project Planets