Upon my shoulder

// TODO: come up with witty tagline

1

In Maven, LESS is less

Sorry, this is a rant.

I was recently investigating Maven plugins for LESS compilation. The use-case is pretty run-of-the-mill (I think?): I want to be able to write a .less file anywhere in my project src/ folder and have Maven compile it to CSS in the corresponding folder in target/ at some point of the build pipeline.

I first looked into lesscss-maven-plugin, a short-and-sweet kind of tool that looks perfect if you have one (and *only one*) target folder for all of your CSS. Working on a large project including things such as separate templates and per-plugin CSS, this would not be working for us.

More reading and research lead me to Wro4j, Web Resources Optimization for Java. One understood the cryptic acronym, it sounds like the kind of all-encompassing tool that the Gods of Bandwidth and Simplicity would bestow upon us mere mortals provided we made the required server sacrifices. A noble idea, but after actually using the thing, it didn’t take me long to drop the religious metaphor.

Wro4j is a horrible mess. There’s absolutely no justification in any way, shape or form for the complexity involved in this plugin. As a perfect example of being too clever for its own good, Wro4j includes several parsers for the configuration file: an XML parser, a JSON parser, and for some reason a Groovy parser. Why you would need three different ways to configure a poor Maven plugin —which should get its configuration from the pom.xml anyway— is beyond me.
And the implementation is the most horrific part: when supplied with a config file, Wro4j will try all successive parsers (yes, even when the file extension is .xml(1)) on the file and end up with this absolutely undecipherable error message if parsing failed with each ‘Factory’. Which will happen when Wro4j doesn’t like your XML configuration file for some reason.

I ended up using a bash script to find .less files and call lessc on them. No it’s not portable, no it’s not “the maven way”, but at least it works and it’s maintainable.

 

1: it takes a special kind of crazy YAGNI-oblivious Java helicopter architect to consider that a Groovy file saved as ‘config.json’ should be a supported feature. In a Maven (which is so heavily XML-based) plugin of all places!

0

Pushing bookmarklets to their limits

I recently had to implement a new functionality for an internal web application: a button to download a specially-formatted file. The right way to do it is, of course, to deploy server-side code generating the needed file in the backend and make it accessible to the user via the front-end. The application in question is an important company-wide production system and I was on a hurry, so I decided to go the Quick way rather than the Right way 1.

Luckily, all the necessary information to create the file turned out to be accessible on a single web page, which meant I could create a user-triggered script to gather it from this page.

There are several ways for a user to inject and run custom (as in non-server-provided) javascript on their machine, such as using a dev console or a dedicated tool like Greasemonkey. But the best balance between ease of development and —comparatively— good user-experience is bookmarklets.

A bookmarklet is an executable bookmark. In practice, rather than being a normal URI such as:

http://example.com

They are of the form:

javascript: /* arbitrary js code */

All a user has to do is to add the bookmarklet to the bookmarks bar or menu of their browser of choice, click on it whenever they want to run the specified snippet of code against the current page, and said snippet will be ran.

To come back to our problem, the task at hand was to gather information on the page and make it downloadable as a text file with a custom extension.

Gathering the information was the easy part — a few strategically-placed querySelectorAll and string wrangling gave me exactly what was needed. The tricky part turned out to be creating a file.

How indeed do you create a downloadable file when you have no access to a server to download it from?

As it turns out, there exists a little-known provision of HTML link tags (<a> — </a>) that allows for embedding files as base-64 encoded strings in the tag’s href element itself. We can control what goes into this tag through javascript, hence we can generate and embed the file on-the-fly!

The last roadblock was to initiate the download action automatically2, rather than requiring the user to click on the bookmarklet, then on a ‘Download’ link. One would think it’s just a matter of clicking the newly-created link. Yes, but… In javascript, creating a link element is one thing, but clicking it is another — Firefox and IE allow the straightforward link.click(), but Chrome has historically only allowed click() on input elements. We have to dig deeper then, and manually generate a mouse event and propagate it to the link element3.

The following bookmarklet is what I ended up using as a prototype. It extracts information from a page, generates a specifically-formatted file containing the information, and fires up the download window:

If you wish to use this code sample to do something similar, remember to strip off comments and delete linebreaks, as the bookmarklet must be on one line.

 

Footnotes

1: the prototype worked, but the use-case I imagined for it turned out to be quite far removed from the true need. I did end up going the Right way ;-), learning a bit in the process though.

2: Respectively presenting the Open with/Save as dialog (Firefox) and downloading the file directly (Chrome).

3: Hat tip to StackOverflow for this technique.

0

Simulating bad network conditions on Linux

Sometimes, your network is just too good.

Today I ran into this issue as I was testing an application running off a VM in the local network. Latency and bandwidth were excellent, as you’d expect, but nowhere near the conditions you’d encounter over the internet. Testing in these conditions is unrealistic and can lead to underestimating issues your users will experience with your app once it’s deployed.

So let’s change that and add artificial latency, bandwidth limitations, and even drop a few packets, using tc.

Just put the following script in /etc/init.d, modify the values to fit your needs, make it executable, and run /etc/init.d/traffic_shaping.sh start to degrade performance accordingly.

I originally found the script on top web hosts’ website, and added a few things. Props!

0

On overflowing stacks

I recently set out to implement a few basic data structures in C for the hell of it (and to reassure myself that I can still code C), and ran into an interesting compiler wart…

I was trying to instantiate a static array of 10 million integers (who doesn’t?), in order to test insertions and deletions in my tree. However, as you can astutely deduce from the title of this post, this was too much for the stack of my poor program and ended up in a segfault – a textbook stack overflow.

I did not think of that at first though, and tried to isolate the offending piece of code by inserting a return 0; in the main() after a piece of code I knew to be working, and working my way down to pinpoint the issue.

Much to my dismay, this didn’t really work out. Why? Check the following code:

Do you think it works with that last line uncommented? You’d be wrong!

[15:20:35]florent@Air:~/Experiments/minefield$ gcc boom.c
[15:20:40]florent@Air:~/Experiments/minefield$ ./a.out
Segmentation fault

GCC (4.2.1) wants to instantiate the array even though it’s declared after the function returns!

Interestingly enough, when you tell GCC to optimise the code, it realises the array will never get reached and prunes it away.

[15:26:06]florent@Air:~/Experiments/minefield$ gcc -O2 boom.c
[15:26:16]florent@Air:~/Experiments/minefield$ ./a.out
Hello world!

Clang (1.7) exhibits exactly the same behaviour.

Lessons learnt? return is no way of debugging a program.

0

Javascript closures as a way to retain state

Long time no blog! Let’s get back into it with a nifty and clean way of retaining state in Javascript – closures.

I was recently looking for an easy way to call a specific function after two separate/unrelated AJAX calls to two remote endpoints have been completed. The naive method would be to make the first AJAX call -> callback to the second AJAX  call -> callback to doSomething, but we can use the fact that these two AJAX calls are not related and run them concurrently. An easy way to achieve that is to:

1. set flags, say initialising two global variables at the beginning of the file:

var callback_one_done = false;
var callback_two_done = false;

2. have each callbacks set its own flag to ‘true’ upon completion and call doSomething
3. check both flags in doSomething:

var doSomething = function() {
    if (callback_one_done && callback_two_done){
        // actually do something
    }
}

But this is a bit ugly, as it litters the global namespace with two flags that are only used there. Instead, thanks to Javascript’s lexical scope we can declare doSomething as a closure and have the flags live inside the function itself:

var doSomething = (function(){
        var callback_one_done = false;
        var callback_two_done = false;
        return function(source) {
            if (source === 'callback_one') { callback_one_done = true; }
            if (source === 'callback_two') { callback_two_done = true; }
            if (callback_one_done && callback_two_done) {
                // actually do something
            }
        };
    }());

What we’ve done here is declare an anonymous function that returns a function. This newly created function, that gets attributed to doSomething, is a closure that contains both the code needed to run and the flag variables. The state is set and kept inside the function itself, without leaking on the outside environment.

Now we just need to call doSomething(‘callback_one’) from the first AJAX call and doSomething(‘callback_two’) from the second AJAX call and doSomething will wait until both calls are complete to run the “actually do something” part.

2014 — Upon my shoulder

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.