Tuesday, 27 September 2016

blojsom is dead...long live blojsom

Today, I taught a class on Lean JEE. What? Let me explain. No, there is too much, let me sum up. 

I believe that JEE as sold in the JEE Blueprint is pretty much bullshit. All web development is—as D. Pierce might put it—an HTTP transaction wrapping some form data going to a persistence store, physically or in-memory, and presenting a response about how that data was stored. After that—as I might say—a thin layer of HTTP session management provides and some UX solves for the synchronous, stateless, HTTP protocol.

Simple, established patterns should be enough for almost every application, even at scale.

This is not to discount the GoF, JEE Patterns, or basic Design Patterns, but judgment and application ultimately trumps a generic "blueprint." My position certainly does not absolve a developer from understanding or grokking the JEE API. One cannot intelligently build anything on any platform without a foundation. Be it PHP, Python, node, Java, or the new money language, COBOL.

And so it was today, applying form best practices such as Get-After-Post, also called Post-Redirect-Get (PRG) or Redirect-After-Side-Effect, and the proper HTTP Response status to such a pattern.

As a production user of blojsom for some ten years now, I consider myself something its "steward." I recently pushed a Mavenized repository to github and have started committing to the project again. Mostly to fix my production build of the web application.

For years, every April for example, I would write posts and Draft them periodically to save entries in progress. This would, if I was not careful, result in entries that would be various versions or states of the post, all drafted and waiting for me to publish them. This is finally fixed.

One of the more recent commits was correcting the rich text editor (RTE) form to use PRG. That took some digging into the Administrative Plugin API and understanding how to short circuit the very procedural process method the EditBlogEntriesPlugin.

Initially, the well-managed session attributes—kudos to David Czarnecki—of the BaseAdminPlugin simply called response.sendRedirect(String). The application now properly does the same, but with a 303 See Other response. Moreover, the calling of super.process(request, response, blog, context, entries) returns from Publish with the 303 and presents the Manage Entries list. 

I'm looking forward to continue working in the code base and improving blojsom in the coming months. Especially before Blogging A-to-Z 2017!

Posted by caffeinated at 7:53 PM in 0xDECAF

Tuesday, 14 May 2013

Addressing CSS2.1/CSS3 @font-face 404s in Internet Explorer

And now for something completely different...

My employer works with several large partners of global brand. Recently, we noted a behavior in Internet Explorer versions 6, 7, and 8--note that we have generally retired support for IE6 and IE7, however a global brand can expose our properties to a large audience that is not technically savvy enough, or cares enough, for lofty principles of supporting core web standards.

The behavior was simply that our Performance Engineering team noted a long term trend of HTTP 404s that periodically spiked with ad campaigns for the brands. The 404s all had GET statements like this:

/webfont.woff')%20format('woff'),%20%20url('webfont.ttf')%20format('truetype'),%20%20url('webfont.svg');

I saw the problem immeditately: IE was reading @font-face rule declarations past the supported type. Let's look at a typical @font-face rule used1:

@font-face {
  src: url(FQURI/to/eot/font);
  src: url(FQURI/to/woff/font) format('woff'),
       url(FQURI/to/truetype/font) format('truetype'),
       url(FQURI/to/svg/font) format('svg');
  font-weight:normal;

}

One can see where the 404 is being generated. The above rule is documented as the preferred way to load the supporting font files across browsers supporting @font-face rules introduced in CSS2.1. The basic idea is that by loading the IE Embedded OpenType format first, IE will "see it," fetch it, and ignore the rest of the font files and types.

I set to solving the problem. 

First, I installed Windows XP SP3 with IE6 and IE7 in dedicated VMs. Then I created a test page with a typical @font-face rule. Using Fiddler, I was able to track and reproduce the 404 behavior. After reading the CSS3 specification carefully, I started looking for parsing tricks that would halt IE from reading CSS declarations.

I was not finding any. 

So I set to using the specification precisely and found the local(font-name) property of the src declaration would stop IE from continuing to read src declarations:

@font-face {
  src: url(FQURI/to/eot/font);
  src: local(font-name),
       url(FQURI/to/woff/font) format('woff'),
       url(FQURI/to/truetype/font) format('truetype'),
       url(FQURI/to/svg/font) format('svg');
  font-weight:normal;
}

I call this the Irish Local Name Method after Paul Irish who documented this method in 2009-2010, but I didn't discover until last week.2

Editor's Note: It seems that fontsquirrel.com has found a less obtuse hack and is leveraging a more readily readable parsing hack and exploiting an MSDN note on support for the format property in IE8 and less3:

@font-face {
  font-family: 'Slab Bold';
  src: url('fonts/slabbold.eot');
  src: url('fonts/slabbold.eot?#iefix') format('embedded-opentype'),
        url('fonts/slabbold.woff') format('woff'), 
        url('fonts/eslabbold.ttf') format('truetype'), 
        url('fonts/slabbold.svg#Slab-Bold') format('svg');
}

The use of the format property achieves the same behavior as the use of the local property, but by restating the Embedded OpenType format property that is ignored by IE8 and less.




  1. [1] Brian Hogan in HTML5 and CSS3 recommends this format.

  2. [2] http://www.paulirish.com/2009/bulletproof-font-face-implementation-syntax/

  3. [3] http://msdn.microsoft.com/en-us/library/ie/ms530757(v=vs.85).aspx To specify specific font formats (only for externally referenced font files), use a format hint (format(fontFormat)) where fontFormat is a comma-separated list of format strings that denote supported font formats. Possible fontFormat values are "woff", "truetype", "opentype", and "embedded-opentype". The format hint is optional starting in Internet Explorer 9. (format hints are not supported in Internet Explorer 8 and earlier versions and are ignored.)

Posted by caffeinated at 2:30 PM in 0xDECAF

Monday, 19 November 2012

server tweaks

I made some server updates, in the truest nerd fashion: on the command line.

Now, testing it.

I'll have a WFRP session recap posted soon from a "lone wolf" session I ran with a friend last night.

Posted by caffeinated at 10:16 PM in 0xDECAF

Sunday, 17 January 2010

Baseball, Politics, and Wargames

I'm an Atlanta Braves fan. I'm not a fanatic, but I own my own official Away play Braves New Era cap (I don't live in Georgia today). I follow the Braves during the season, but do not count the days to spring training, as a fanatic might.

If you read my bio, you'll find that I'm a capitalist, right leaning, and unaffiliated voter.

And I'm a nerd. I like wargames in the old school vain: hex maps and chits. As such I follow the niche market this is wargaming, and having recently received Multiman Publishing's PanzerBlitz: Hill of Death, I follow the publisher pretty closely.

Through this "deep linking" I know that a central partner/owner of Multiman Publishing is, the Boston Red Sox's own, Curt Schilling.

I got the biggest chuckle this morning reading the NYT (yes, I read the NYT, and subscribe to WSJ) capturing the gaffe of MA Senatorial hopeful Martha Coakley suggesting Curt Schilling was a Yankee fan, Coakley on Schilling: A Yankee Fan?

Coakley made the suggestion as Schilling is "shilling" for her political opponent. Curt Schilling is, in bean town, nothing less than a Boston Red Sox fan's hero. Trust me when I say, Curt Schilling is not a Yankee's fan. Gaffes of this caliber sink candidacies.
Posted by caffeinated at 1:12 PM in 0xDECAF

Friday, 8 January 2010

A year of caffeine, 2009 in summary.

I have several analytic tools running on ACD.

Google Analytics and a very robust log parser on the server side.

At the end of 2009, my log analytics reported 13,554 unique visitors. Now, this really is nothing more than 13,554 unique IPs that do not necessary mean that 13,554 unique people visited ACD, but it's not bad. In 2008, it was 10,712. That's a 28% increase.

Yet, the topics of interest that lead people to ACD changed between 2008 and 2009. In 2008, I was doing more sysadmin blogging and a lot of hits came to topics that provided some help to others trying to compile binaries on Linux.

In 2009, WFRP got the attention. My Inns of the Empire tool got a lot of hits, and I started seeing a lot of activity on my WFRP campaign wiki.

Google Analytics provides some more insight, and some sobering insight, like bounce rates. "Bouncing" shows hits that arrived and found nothing of interest and move on, immediately. It's soul crushing data.

Where people come to ACD is exciting. Britain and much of continental Europe find the website according to Google. The Map Overlay tools are always fun to use and drill down to localities.

I also started using some of the linking data in my signatures in 2009, and those linking to the Inns of the Empire tool where given special links for tracking.

For the 6 months of 2009 that used this linking (where I even went out of the way to ask that those linking to ACD update their links, which they did! Thank you Chuck and KVH), Winds of Chaos, a premier WFRP resource blog, lead the way. Kalevala Hammer followed a close second. My forum sigs also got some click throughs.

Google Analytics also told a different story about the visitor patterns, significantly changing the values of the log parser, by 10K or more. "Absolute Unique Visitors" were only 2,050! Not as exciting. Log parsers are notoriously dangerous engines to quote numbers from, so I'm inclined to look at Google's numbers with more weight. Google does validate the traffic patterns that my log parser reports, WFRP searches were big in 2009.

All said, 2009 was a good year. I really do want to make 2010 a much more exciting WFRP and ACD year!
Posted by caffeinated at 10:24 PM in 0xDECAF

Monday, 21 September 2009

Some nice configs

Besides roleplaying, I'm a "strategic web architect" in my day job.

I build a lot of software on my laptop and have more than an occasional need to have configurations handy for builds.

Here are three configs I often need and thought I would share (making them remotely handy as well):

Of course they do you no good on a Windows workstation, but might be helpful on Linux and Mac OS X. Be sure to look at each one for specifics to your platform. These were used to build an Apache service with SVN support.

Posted by caffeinated at 9:17 PM in 0xDECAF

Thursday, 4 December 2008

Iron Hill Triple Bock

I removed the cork from the 12USD bottle of Iron Hill Triple Bock this evening.

Tasty. A 13.2% ABV, 31 IBU, dark porter worth the 12 bucks.

Most interesting was its nose and palette. It immediately harkened me back some 10 years to when I brewed my own beer. I never advanced to get the color right, but I got the body and taste to my satisfaction over and over again. This beer took me back immediately. I could smell it on the nose and taste it. Chocolate and coffee. Heavy roasted malts and sweet bite of hops.

Worth 12 bucks? Yes. Would I buy again? Can't tell. I need to see what a more commercial brewer does with their Triple Bock, e.g., Samuel Adams. But I would consider it as a special opportunity, like a good cigar.

Recommend? Yes. If you can get it, worth the glass!

Posted by caffeinated at 9:01 PM in 0xDECAF

Sunday, 4 May 2008

I Am Legend: a review

Horror, as I told a friend just last night, is not something I seek out. If so, it is usually pulp horror (Blade), or campy horror (Lost Boys). I did like 28 Days Later.

I Am Legend is 28 Days++. I was literally on the edge of my seat for the first 2/3.

The last 1/3 though was, well, long.

I think I wanted more closure on the “zombie love story.” Wha? Clearly, there was something about that one zombie’s determination after Neville captured “the girl.” There was something in the passion of the zombie. The trap, mimicking Neville. The dog pack. The “leadership!” And it all boiled down to the zombie just committing suicide, for all the determination to break down the wall, with Neville pulling the pin.

And, I’m sorry, but three years would have exhausted any food supply for the zombies, whatever that food supply was. 28 Days Later was much better about that: the zombies so weak, they couldn’t even stand up.

Unrelated to I Am Legend was the Lost Boys: The Tribe trailer. Here’s my 2 brass pennies on this MTV straight-to-DVD vehicle. It's going to be Crap, because the trailer is painful to watch.

Only one of the Frog brothers? You can't have a Lost Boys sequel with only “one Corey.” Why waste the film stock on this if you’re not going to get both Coreys, Patric, Gertz, and Wiest. They all survived and the actors are all still alive. I think the nod to the original with only Feldman, painfully delivering lines like "...Edgar Frog: board shaper, vampire hunter...," or something like that, say a lot about the reason it won’t have a theatrical release.

Posted by caffeinated at 1:16 AM in 0xDECAF

Thursday, 10 April 2008

A Weekend in the Mountains

I'm off with my daughter to the Land of GA. We are visiting family and I'll be spending two nights in the mountains of GA with high school and college friends. Fishing, drinking, shooting, drinking, reading, drinking. Did I mention drinking?

Year Two of the, hopefully, annual excursion.

It's tempting to start playing banjo music and conjuring images of Deliverance and pigs. Alas, while funny, not that kind of trip.

Its been quiet at ACD. It will be quieter still for a few more days.

Posted by caffeinated at 8:21 AM in 0xDECAF

Thursday, 27 March 2008

Code horror

Here's something that was brought to my attention this evening, when I should be working on encounters for a Friday night WFRP game... no, instead I'm working. Literally. On a production problem. For my employer.

Scenario: a badly written stored procedure has a race condition. Instead of fixing the stored procedure, get the web geeks to fix it on the front end with Javascript. Problem: double clicking a submit button inserts duplicate records in the backend. Solution: stop users from double clicking, because fixing the database or the stored procedure is not the place you want to fix this problem. Whatever.

Assignment: get a flunky in a remote production support facility (we haven't left the US, fortunately) to craft a Javascript function that would prevent the form from submitting twice.

var submitted=0;
function checkAlreadyDone() {
        submitted++;
        if (submitted < 2) {
                document.forms[0 ].submit();
        }
}

There are a couple of problems with this charlie foxtrot. The first being the zero-indexed variable and the boolean check for less than 2! WTF? is that. Why not a boolean? It's easier to read. Now I have to do math to review the code. It's true or false! The second is I have think about what the variable state is on the round trip of the submission. 0, now 1, or less than 2. It changes to often.

I wanted to cry. And not just because the really broken code: the stored procedure and the database aren't going to be corrected, but because this is just badly written. The flunky never even requested a code review, never tested it because the call to the forms array was submitting the wrong form and creating a Javascript error in the browser! and basically broke the functionality of the page for over 6 million users.

Posted by caffeinated at 10:37 PM in 0xDECAF