More Projects

JSONView is back

On November 14th of 2017, Firefox 57 was released, and JSONView stopped working. This was not unexpected - Mozilla had been warning for a while that they were going to shut off their old extension system completely and move to the WebExtension system pioneered by Google Chrome. All of the Firefox extensions using the old system were silently disabled.

I had hoped to have a new version of JSONView available that was compatible with this new system before Firefox 57 released, but unfortunately the deprecation coincided with a crunch period at work and I wasn’t able to make the time. However, last month I had a chance to relax for a bit while out of town for my wife’s show at Archimedes Gallery in Cannon Beach and I took a couple hours to hack out a WebExtension version of JSONView.

I had always been hesitant to write a WebExtension version (or a Chrome version) because the way JSONView works on Firefox is that it actually intercepts the request and rewrites it into HTML. Existing Chrome ports of JSONView ran on every page load and did stuff to try and rewrite the page, imposing a cost and a security exposure to every page. However, Firefox’s implementation of WebExtensions includes StreamFilter which lets me intercept and rewrite content in the same way as I did before!

Once I had a version working on Firefox, I got something working on Chrome as well. This works differently because StreamFilter is not available on Chrome, so I use a technique that still reformats the page after it loads, but it figures out which pages to act on in a fast, safe way. Thus, for the first time, there is an official JSONView for Google Chrome. If and when Chrome supports StreamFilter, JSONView will start using it transparently, with no changes required.

There are a few bits of functionality that had to be left behind. JSONView had the option to add application/json to your Accept header in order to convince APIs using content negotiation to serve JSON. That turned out not to be a popular way to write APIs, and JSON has since won over XML completely, so this option isn’t as necessary. On the plus side, the method by which I detect content types that contain JSON is much more flexible now, so any content type matching application/*+json will now work with JSONView as well - a long standing feature request.

On Firefox, you may notice that local files open in Firefox’s own JSON viewer instead of JSONView. To fix this, go to about:config and set devtools.jsonview.enabled to false.

JSONView remains a mature project that doesn’t need to change much, but I’m really happy that people can continue using it, and now Chrome users can get the same experience. If you don’t already have it, download JSONView for Firefox or Chrome.

The state of JSONView in 2017

I released JSONView in early 2009 to solve a simple problem I had - I’d been working with a number of JSON APIs, but Firefox had no way of directly viewing JSON documents. At the time, it wouldn’t even display them as text, showing a download dialog instead. Even after Firefox started showing JSON as text, it was still useful to show JSON nicely formatted and highlighted rather than however it was served. In the nearly eight years since its launch, JSONView has grown to about 130,000 daily users and has been downloaded 1.5 million times.

Once the initial few versions were out, I’ve updated JSONView on average every six months. Following that trend, I released JSONView 1.2.0 in late November. I’ve expected Firefox to subsume JSONView’s functionality ever since I first launched it, but amazingly this hasn’t happened yet. That said, Firefox has recently gained a very nice native JSON viewer hidden behind a developer flag (that’s only on by default in Firefox Developer Edition) and JSONView now offers the option of simply turning on that viewer instead of doing its own thing. Hopefully soon, JSONView won’t be needed at all.

I’ve always applied a minimalist philosophy to the extension. I’ve resisted adding a lot of bells and whistles in favor of a simple extension that does one thing well. This has the side-effect of reducing the rate of change of the extension, since besides the constant work of keeping it up to date with changes to Firefox, it’s pretty much done. There are still capabilities I’d like to add to JSONView, but those that haven’t already happened are usually impossible within the bounds of Firefox’s extension API. Speaking of which, Firefox is generally moving away from the sort of deep integration for extensions that JSONView requires - I hope JSONView is completely obviated by the time it can no longer work at all.

I personally don’t use JSONView anymore at all, because I no longer use Firefox. When I interact with JSON APIs I make use of the Chrome devtools, Emacs restclient-mode, and the jq and gron command-line tools. I’ve continued to maintain the extension, which remains open sourced on GitHub with several contributors helping out over time.

JSONView has been cloned, without permission (but without any resistance - it’s open source after all) as a Chrome extension in at least two instances. One of them became very popular but has been abandoned and is no longer on the Chrome web store because it contains security vulnerabilities. I never made a Chrome version myself because Chrome doesn’t offer the same integration APIs that Firefox does, so I couldn’t make it work the same way. JSONView for Firefox intercepts requests for JSON documents and produces HTML instead. The Chrome ports run on every single page that Chrome loads and try to figure out whether it looks like a JSON document, then reformats the document in-place. I never liked the security and performance implications of that, so I’ve avoided an official port. I keep an eye on Chrome’s extension API in case it ever becomes possible to do things the way I want to.

In summary, JSONView the Firefox extension is doing well, but is a mature project that will change slowly, if at all. JSONView for Chrome appears to be dead, and I don’t have immediate plans to produce an official port myself, but I won’t rule it out and I’d accept a well-implemented contribution as long as it matched the design and implementation philosophy of the original.

Save time runnning FindBugs by excluding SQL checks

FindBugs is a great tool to help you find tricky problems with your Java code, as well as to learn more about Java best practices. Unfortunately, for a large codebase, FindBugs can be extremely slow, often taking several minutes to run. In the last few years, the Java projects I’ve worked on haven’t made use of SQL databases, and I recently discovered that FindBugs’ checks against SQL injection make up a major portion of the overall runtime for the tool. Try creating a findbugs-exclude.xml file, and putting the following in it:

<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
  <!-- We don't use SQL or JDBC, so remove these very expensive bug detectors. -->
  <Match>
    <Bug code="SQL,ODR" />
  </Match>
  <Match>
    <Bug pattern="DMI_CONSTANT_DB_PASSWORD,DMI_EMPTY_DB_PASSWORD" />
  </Match>
</FindBugsFilter>

In my experience, this shaved a whole minute off a multi-minute FindBugs run, with no downside since we don’t use any SQL or JDBC. Of course, if you do use those technologies, these scans are probably still worth the time!

Node.js stack traces in Emacs compilation-mode

, ,

I’ve been using Emacs regularly for at least 10 years, for all of my programming tasks that don’t involve Java or .NET. Amazingly, for most of that time I’ve used a pretty stock installation of Emacs with only a few cargo-culted customizations stolen from my co-workers’ .emacs files. However, as part of switching to a new job in the last month, I’ve taken the opportunity to invest in my shell and editor, and I’ve fallen deep down the rabbit hole of Emacs customizations. My continually-evolving config is publically available on GitHub. The difference between stock Emacs and one loaded up with custom packages is astounding - I can’t believe that I had been missing out on all of this. But this is not an article about setting up Emacs to be your perfect editor. Instead, I wanted to provide a tip for Node developers that I hadn’t found the answer to when I went looking.

The other day I was working on a Node.js script, and I was constantly switching back and forth from Emacs to the terminal to run the script, hit some error, remember the line number, go back to Emacs to look up the error, etc. Then I remembered that Emacs has the compile command, which will run a shell command and show the output in a separate window. Now I could split my frame into two side-by-side windows, edit my script on the left, and run compile to test out my script with any test command I liked (and then use recompile or g in the *compilation* buffer to re-run the command). But there’s another neat feature of compilation-mode - it can understand stack traces and provide hotkey access to the line that triggered an error. Unfortunately, the stack traces from Node were not being recognized correctly, and Emacs thought the last number was the line number, when it’s really the column number.

To fix this, I simply needed to add a new regexp to the list of patterns compilation-mode understands:

;; Add NodeJS error format
(setq compilation-error-regexp-alist-alist
      (cons '(node "^[  ]+at \\(?:[^\(\n]+ \(\\)?\\([a-zA-Z\.0-9_/-]+\\):\\([0-9]+\\):\\([0-9]+\\)\)?$"
                         1 ;; file
                         2 ;; line
                         3 ;; column
                         )
            compilation-error-regexp-alist-alist))
(setq compilation-error-regexp-alist
      (cons 'node compilation-error-regexp-alist))

Writing that regexp would have been hard, but of course Emacs has a solution. First I found the current value of compilation-error-regexp-alist-alist using describe-variable in order to get an example regexp to start with. Then, in the compilation buffer where my stack trace was, I ran re-builder, which pops up a little mini window where I could tweak my regexp and see immediately whether or not it was matching correctly. Then I just added this to my init.el, evaluated it with eval-region, and my next compile had the errors highlighted correctly, and I could immediately go to the offending code with next-error or by putting the point on the stack trace line in the compilation buffer and pressing RET.

Hopefully this helps out some fellow Emacs-using Node developers, and serves as a reminder that your tools can always work better for you.

Converted GoPro Videos Don't Work in iMovie on Yosemite

,

Update June 25, 2015: iMovie 10.0.9 has been released which fixes the problem I describe below.

Recently, I’ve been enjoying using my GoPro camera with iMovie to put together silly little videos. I recently upgraded my MacBook to OS X 10.10 Yosemite, and at the same time accepted the automatic upgrade of iMovie to version 10.0.0.6. After doing so, I realized that all my previously-imported GoPro videos wouldn’t play in iMovie anymore, showing as “empty” tracks instead. I also couldn’t import converted video into iMovie anymore.

iMovie not playing GoPro Videos

To back up a bit, I’ll explain how I usually work with GoPro videos. I shoot video with my GoPro using the “ProTune” mode, and then import those videos onto my Mac. From there, I convert them into an editing-friendly CFHD (CineForm HD) format using GoPro Studio. GoPro Studio understands ProTune, and offers nice color correction and exposure controls - much better than iMovie can offer. After color correcting the clips, I’ll import them into iMovie and then deduplicate them using a script so that I can still use GoPro Studio to make further color tweaks while editing in iMovie. I can then use iMovie, which I quite like, to edit my videos, add music, etc.

Unfortunately, that workflow is now broken because iMovie no longer recognizes the CFHD video format. It can import the original, pre-converted videos from the GoPro, but thanks to the ProTune recording mode, those videos require extensive color manipulation to look good (which GoPro studio does as part of its conversion process). To work around this limitation, I’ll either have to switch to doing all my video editing in GoPro Studio (which is pretty limited) or export my videos to an h.264 encoding from GoPro Studio so iMovie can use them. I’m not really excited about the latter option as that means yet a third copy of my video, and I won’t be able to tweak videos in GoPro Studio after I’ve exported them.

I’m not sure exactly what’s going on, but if I were to hazard a guess it’s that OS X Yosemite and iMovie 10.0.0.6 are continuing with Apple’s migration away from Quicktime (which allowed for third-party video codec plugins, like CineForm’s CFHD plugin) to AV Foundation, the media framework from iOS that Apple has brought back across to OS X. Unlike Quicktime, AV Foundation only supports a limited set of video formats, and does not allow for external plugins that add support for other formats. This is why, for example, Perian no longer works. I had hoped that iMovie, being cut from the same codebase as Final Cut Pro, would be exempt from this dumbing-down. I wonder why this happened, without announcement, and in a point release of the software. I’m also not sure, if this is really the case, what GoPro/Cineform could do about it now that Apple has closed off any avenue for third parties to extend OS X’s media capabilities. It certainly doesn’t make me want to jump up to Final Cut Pro and wonder whether things would be better supported there.

That said, I haven’t done a lot of extra research to validate my theory. I haven’t confirmed that other formats no longer work with iMovie, and I haven’t tried a Mac with Yosemite but without the new iMovie to help narrow down which one may have introducted the change.

I’ve searched around for reports of other people having this problem, and I’ve found a few Apple support forum posts (no answer) but not much else. I opened a support ticket with GoPro, but they were clueless and eventually stopped responding to me. My hope is that by documenting this problem, this post will at least be somewhere for others in my situation to commiserate, or even better, to tell me I’m wrong and I just need to do X to fix everything.