It’s kind of a cryptic procedure, but this method really works for debugging the mysterious “SEVERE: Error listenerStart” I’ve been getting when a Spring app fails to load.
Set 3 Breakpoints at org.spring.EyeOfNewt…
Physical addresses and SEO
By pjmorse | Posted on September 15th, 2009 | No CommentsWe only have our tongue a little bit in cheek when we say if you really want to improve your search engine results, you might want to consider relocating.
By way of example, let’s consider what happens when you search for “web development” near Amherst, MA. Google Maps shows results ordered by proximity to the center of town, and guess which web development company has an office closest to the center of Amherst?
When the Amherst College development offices move on-campus, there will be some closer-to-the-center addresses available, just in case you thought geography was irrelevant in today’s virtual world.
Clean out role-user mailboxes
By pjmorse | Posted on September 14th, 2009 | 1 CommentI suppose the subtitle to this post could be, “why you don’t want to be a mail administrator.” The fact is, spam has made running a host which accepts email a pretty unpleasant task all around, and we strongly suggest clients we host domains for run email for that domain through Google Apps rather than relying on POP/IMAP through our host.
We do still have a box which accepts incoming SMTP, though, and that means putting up with a certain amount of unsolicited commercial overhead. Every Linux box has a certain number of no-shell users set up to run daemons with limited privilege, e.g. the apache user. Oddly, some spammers either run the same username scans as the brute-force ssh hackers, or they think the apache user is actually reading its email. I found 44MB of unread email, about 5,000 messages, waiting in that inbox. uucp had the next biggest collection; mail and news were right up there as well.
That’s a lot of disk space. After a cursory glance to ensure there was nothing actually important in there, I simply used sudo cp /dev/null /var/spool/mail/apache to take out the trash.
If you are root or have appropriate sudo privileges, you can check another user’s mail using mutt or a similar command-line mail client. Just use the -f flag to feed mutt a mailbox path as an argument. In this case, I could check the apache mailbox using sudo mutt -f /var/spool/mail/apache . Naturally, you would want to have a talk with your company ethicist before doing this on a mailbox belonging to an actual user.
The best shortcut here is to bounce any email destined for the role users. This will vary depending on your MTA, so I won’t detail it here.
XSL namespaces for HTML output
By pjmorse | Posted on July 15th, 2009 | No CommentsOne of our current projects involves an application where certain PHP scripts request XML from a SOAP service, then use XSL templates combined with parameters set by the PHP script to generate XHTML from that XML. (Follow that? If not, you may be able to safely skip this.) We haven’t had to cope with setting up this system, but we did have to update the HTML produced by the XSLT, if that’s the proper verb.
The problem we ran in to was getting around Internet Explorer’s quirks mode. The original XSL templates use a bare xsl:output tag with few options, and a bare html tag to start the output code as well, like this:
<xsl:output method="html" indent="yes"/> <html>
This produces HTML with no document type and no XML namespace, which means IE is going to go to Quirks Mode, which we don’t want because it hurts our carefully-crafted CSS. We want something more like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml: lang="en" lang="en">
First, we tried just adding the xmlns attributes to our html tag. This didn’t really help: it added extraneous xmlns="" attributes to many of the child tags in the output document, which quirkified IE just as much as not having the tag.
Solving the second part of the first problem (producing a document type tag) turned out to also be the solution to the second problem (extraneous xmlns attributes). XSLT will add a document type tag automatically if the appropriate attributes are given to the xsl:output tag. Specifically, we wound up with this:
<xsl:output method="html" indent="yes" encoding="utf-8"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
Notice the bonus encoding, doctype-public and doctype-system attributes. That got us the DOCTYPE tag shown above, and bailed us out of IE Quirks Mode.
Passenger, Paperclip, and Permissions (another route)
By pjmorse | Posted on June 9th, 2009 | No CommentsWe had issues with file uploads recently on a site using Paperclip to handle uploads and served with Passenger. The site worked fine in development, but in production the uploads would fail. Checking the production log showed that Paperclip was producing the following error:
[paperclip] An error was received while processing: #<Paperclip::NotIdentifiedByImageMagickError: /tmp/passenger.1358/var/stream.25635.1 is not recognized by the 'identify' command.>
A web search produced this railsforum thread with some helpful advice, specifically to set
Paperclip.options[:command_path] = "/usr/local/bin"
in an initializer for Paperclip. Our problem was environment-specific, though, so we put it in the config/environment/production.rb file instead. No luck.
So I checked the Apache logs to see what error Passenger was producing. It wasn’t throwing an error of its own; instead we were seeing a lot of
[DEPRECATION] S3 support through RightAWS is deprecated. S3 support will be changed to AWS::S3 in a future version.
…in the Apache error log. It turned out that our development boxes were all using the aws-s3 gem, and the production box was still on RightAWS. When we installed aws-s3 on the server, the problem was solved.
So if you’re having Passenger and Paperclip problems, make sure you’re using the right interface with s3 as part of your troubleshooting process.
Baseline, Software Licenses and Services Agreements
By pjmorse | Posted on May 29th, 2009 | 1 CommentThis is probably not the best place to be tracking the step-by-step growth of Baseline Solutions, but we’re proud of the software package we built for them, and it’s nice to see other people saying good things about it as well.
The most recent upgrade added software licenses and services agreements to the kinds of documents the application handles, and Jeffrey Gordon of the Software Licensing Handbook gave Baseline a run-through before agreeing to allow his templates to be used as Baseline “playbooks”. Gordon captures neatly the advantage the Baseline application gives to a legal review team (emphasis ours):
You upload your preferred language (the baseline information) and then you can bounce any other proposed agreement off your preferences. The software uses proprietary algorithms to review the wording and match the sections. It looks for common phrasing but also appears to recognize intent. Frankly, I’m not sure how it works, but it does.
… The result is that the first review … is accomplished in a few seconds. The basic review is complete – now I can spend my valuable time reviewing the unique contract issues. I’ve just saved time and produced a better document.
We especially like where he calls it “Pop-Up Video for your contract.” (We do know how it works, and we’re still impressed.)
Rails incorrectly caches RSS feed as HTML
By pjmorse | Posted on May 26th, 2009 | 1 CommentHere’s the scenario: a site with a page which is served in two formats. http://www.example.com/sample returns HTML, and shouldn’t cache it. http://www.example.com/sample.rss returns an RSS feed, which should be cached. In Rails, we should be able to achieve this by including this code at the top of the controller:
caches_page :sample, :if => Proc.new { |c| c.request.format.rss? }
What this is saying is, if the format of the request is rss, cache it; otherwise, don’t. Because this was page cached, it would create a file public/sample.rss which would get returned in response to any requests; deleting this file equates to invalidating the cache.
The symptom we started seeing, irregularly, was that suddenly http://www.example.com/sample would return RSS. This turned out to be because the RSS feed was getting saved in public/sample.html. To solve the problem, we had to figure out how the RSS feed was getting cached as if it was HTML.
The answer turned out to be a poorly-formatted URL. If you request http://www.example.com/sample?format=rss, the response is (correctly) RSS, but the extension of the cached file is (incorrectly) .html.
In order to work around this bug, we removed the caches_page line from the top of the controller, and instead used cache_page within the response block of the action in question. cache_page accepts two parameters, the string to be cached and the key (the path, in this case) to cache it at, so we could force the cache filename.
respond_to do |format|
format.html
format.rss {
render :layout => false
cache_page(@response, "/sample.rss") }
end
The result here is that HTML is never cached (as required), and when RSS is cached, it is always cached with an .rss extension. The drawback is that the funky URL will never get a cache hit; it will always be generated from Rails (and update the cache while it’s at it). However, that’s an acceptable trade-off for not generating bogus cache files in the first place.
The kludgy part of this–aside from needing to do it in the first place–is using @response in the controller, which we’re not supposed to do. I wish there was a more elegant way of getting the content of the response for caching.
I think this is a bug somewhere in Rails’ caching code, but I haven’t yet dug in to see where or how it could be fixed.
The problem with our office
By pjmorse | Posted on April 27th, 2009 | No CommentsWe moved in to this office in November, and it was already pretty chilly. It’s warmed up enough now that we’re opening the windows a bit, and we’ve discovered this means the office smells like a kitchen. More specifically, it smells like Bueno Y Sano.
More positive press for HitFix
By pjmorse | Posted on April 25th, 2009 | No CommentsBack in March, our friends at HitFix got some press from BusinessWeek, which listed them among “America’s Most Promising Startups.”
Template building
By pjmorse | Posted on April 22nd, 2009 | 1 CommentAnother area CMI works in is taking complete designs from clients and rendering valid (X)HTML and CSS from the design documents. It feels like a pretty basic service, but it frees designers (who know what looks good) from the requirement of knowing HTML, and lets them create functional and interesting designs without worrying about how they’re going to realize them in markup. From the other direction, letting design proceed in parallel with code development means the developers won’t find themselves with working code and undesigned pages, a situation which (in our experience) usually leads to launching with a rushed and poorly-thought-out design.
We’ve mentioned our work on FlyFi before; the designers, Corey McPherson Nash, recently sent out a press release highlighting their role in the project.
Another project we worked on over the winter recently went live when Running USA launched their new site. Running USA, a trade organization promoting the sport and industry of running, started down the site overhaul road nearly a year ago. We consulted with them over the summer, assisting them in identifying the major issues to be addressed by a new site, drafting the eventual RFP, and advocating implementation of particular technologies. As the project moved forward, we worked with the project managers (a company apparently so busy they don’t have a completed website yet) to turn their wireframes and comps into valid templates.
In both cases, our deliverables don’t look like much in a desktop folder: a few .html files and even fewer .css files. But being able to count on the templates to deliver (and across browsers – thanks, Litmus) isn’t measured in file counts.