The Dopefly Tech Blog

« The Dopefly Tech Blog Main page

LESS in Java: Running LESS CSS on the JVM

posted under category: CSS on September 13, 2011 by Nathan

Foreword: I am giving a LESS CSS talk at the Adobe MAX 2011 ColdFusion Unconference. Blogging about LESS is just one of my stepping stones to presenting. If you want the really good stuff, you should come to my session!


I recently blogged about LESS ports to other platforms, and I thought about mentioning Java there, but this is not a port so much as just reusing the native implementation. Let me break it down like this: Yes, LESS runs on the Java Virtual Machine. It's not even that hard. How you may ask? Like this...

Mozilla makes browsers and Javascript engines. One of their Javascript engines is called Rhino, a JSR 223 compliant Javascript engine for the JVM. You can run any Javascript in Rhino, except that there is no browser, no window, no document and no DOM (I know, it sounds like a dream come true). The conflict comes where LESS.js relies on browser constructs to get its job of compiling and preprocessing LESS CSS into plain CSS, so we have to defeat that.

Lucky for us, we live in the future, and along with our flying cars, we also have Google and GitHub, which pointed me to Asual's project, lesscss-engine. Asual is a software company in Bulgaria, and their GitHub projects are run by Rostislav Hristov.

The easiest method of setting up Asual's solution is to download his browser.js and engine.js, then from Rhino, within Java, include them in the order of browser.js, less.js, then engine.js - the order is important. I did this in an Ant build file like this:

<script language="JavaScript" src="browser.js" />
<script language="JavaScript" src="less.js" />
<script language="JavaScript" src="engine.js" />


From there it's just a matter of calling the engine methods to load LESS CSS code, convert it to CSS and output to a file. Here is how I did it, this is my code that is directly after the script loading:

<script language="JavaScript"><![CDATA[
var inputFile = readFile('input.less');
var css = compileString(inputFile);
writeFile('output.css', css);

function writeFile(filename, content) {
var fstream = new java.io.FileWriter(filename);
var out = new java.io.BufferedWriter(fstream);
out.write(content);
out.close();
}
]]></script>

The engine.js has a number of good helper methods (readFile, writeFile, compileString, etc.), I did it this way in case there were more LESS files to compile and I wanted to add it to the same css output string. When you do this, make sure you have the Rhino file, js.jar, in your Ant classpath. In Eclipse I loaded the external jar by adding it to the 'Run as...' dialog when you right-click on your build.xml file. Also make sure you are on Java 1.6+ to support JSR 223 Java Scripting.

You aren't limited to compiling LESS when you do this, you know. You can actually do anything you want in Javascript from right inside your Ant build file. It's fantastic.

There are other methods of accomplishing the same goal. Erwan Loisant did something similar by altering the core LESS.js files (including the proper pull request). While he calls his release LESS for Rhino, it's really more of LESS for Ant. Even still, it works great as a rhino-javascript-ant all-in-one solution. I especially like his use of an Ant macrodef to create a <lessjs> tag. His examples work straight across from his blog, perfectly.


Not content to rest on my laurels, I went back to the Asual's LESS Engine project to see if I could make a jar and see what I could do with it. I cloned the GitHub repository locally over http, then I added it as a project to Eclipse. I had to install Maven, which was simple with Eclipse's software installer, and running it is almost exactly like running an Ant build. When you build the project you get a few jars in the target/ folder. I recommend using the lesscss-engine-1.1.4-jar-with-dependencies.jar file, as it's the most likely to work anywhere you need it.

When I checked the LessEngine class, I noticed a main method that was added recently, which means we can call it from the command line, like so:

java -jar lesscss-engine-1.1.4-jar-with-dependencies.jar input.less output.css


Incidentally, if Asual (or someone) were to add a -w command line switch to watch the input file for changes, this would essentially make it identical to the Ruby LESS compiler, lessc. Except, of course, it would be much faster. Just a thought.

So we can call it from the command line. The next, most obvious step, is to put this in an Ant build. This was so simple. Here is what I did:

<java jar="lesscss-engine-1.1.4-jar-with-dependencies.jar" fork="true" dir="${basedir}">
<arg value="input.less" />
<arg value="output.css" />
</java>


Copy and paste that, with the jar, and it will all work as advertised.


To summarize, You can compile LESS on Java. It's fun and easy to do!

If you want to get all the files, or want to see it in action, I'm doing this talk September 28, 2011 at the AZCFUG in Tempe, AZ, then at Adobe Max on October 5th, then again October 12th at the Tucson CFUG. Look forward to more of this kind of chatter here on this blog.

Nathan is a software developer at The Boeing Company in Charleston, SC. He is essentially a big programming nerd. Really, you could say that makes him a nerd among nerds. Aside from making software for the web, he plays with tech toys and likes to think about programming's big picture while speaking at conferences and generally impressing people with massive nerdiness and straight-faced sarcastic humor. Nathan got his programming start writing batch files in DOS. It should go without saying, but these thought and opinions have nothing to do with Boeing in any way.
This blog is also available as an RSS 2.0 feed. Click your heels together and click here to contact Nathan.