Thursday,
5 Nov 2009
LESS for Java
LESS is a cool project that has been around for a while and extends CSS with a few nice features like variables, mixins, operations and nested rules. The best thing about it is the syntax that feels very natural and easy to learn. I was eager to play with LESS but the main stopper for me was the fact that it is written in Ruby and I'm mostly involved in pure Java projects. It seems that my desire to try it was really strong because I sat down and lost almost a weekend in learning how JRuby works and finally produced a working prototype that only requires the Java 5 Virtual Machine. Over the last two months I was able to totally reorganize, extend and test the code base and I'm now finally glad to release it officially.
LESS for Java is a set of 2 modules that primarily target Maven 2 compatible projects but can also be used in any Java enabled environment:
- LESS Engine contains the original LESS codebase and provides a straightforward access to the underlying API. It has been designed as a core module that can be used various scenarios.
- LESS Servlet automatically compiles and serves LESS sources but also supports other resources like image and script files. It optimizes the server response by adding appropriate headers and applying the YUI Compressor for both CSS and JavaScript requests.
Both modules are already available on the official Maven 2 repository and you can start playing with them immediately. The current 1.2.11 version matches the snapshot of the original LESS distribution that has been used. The project has been successfully utilized on this website as well as in a bigger project built around Spring MVC and JSF. The source is available on GitHub where we're planning to put all our new open source stuff. Comments and feedback are welcome.
Comments:
The initialization of the JRuby engine is slow but after that you can compile CSS at fairly good speed. Have you tried that? I'm also processing files at runtime and I have put various optimization efforts in the LESS Servlet module. You can get some more info from this thread.
It's great to see the dependency on the original Ruby project rather than trying to write it from scratch ... makes it a lot easier.
Be well.
I have integrated your library into wro4j (an open source project used for web resource optimization for java): http://code.google.com/p/wro4j/ . The latest release (1.2.6) integrates your library! Keep up a good work!
* avalon-framework-4.1.3.jar
* commons-logging-1.1.jar
* commons-logging-api-1.1.jar
* jruby-complete-1.4.0RC1.jar
* lesscss-engine-1.2.11.jar
* lesscss-servlet-1.2.11.jar
* log4j-1.2.12.jar
* logkit-1.0.1.jar
* slf4j-api-1.5.6.jar
* slf4j-simple-1.5.6.jar
* yuicompressor-2.3.6.jar
However my Tomcat still gives a non-standard 404 message for any css files (I have '/*.css' mapped to the servlet), and there is absolutely nothing in the logs. Any ideas?
Can you please try downloading the latest version from GitHub. It contains lots of improvements and uses the new less.js codebase that requires Rhino instead of JRuby.
You can easily see what's going wrong with a little debugging. This website runs version 1.2.8 and I don't have the following in my lib folder:
* avalon-framework-4.1.3.jar
* commons-logging-api-1.1.jar
* logkit-1.0.1.jar
* slf4j-api-1.5.6.jar
* slf4j-simple-1.5.6.jar
Excellent, thanks, I'll do that straight away as I think we've had bad experiences with JRuby reliability in the past, so using Rhino will keep everyone much happier at the company. As it happens, in the meantime, I managed to figure out what the problem was anyway: I had to turn off the GZip compression we run here even though I didn't have compression enabled in LessCss (I think!); I'd removed this config from my servlet config, but the only thing that helped was disabling our main GZip compression filter:
<init-param>
<param-name>compress</param-name>
<param-value>true</param-value>
</init-param>
Anyway, thanks loads for your help here!!!
I've switched to 2.0 and Rhino, and not only does it work, but it delivers the first result much much faster. I couldn't get 'mvn install' for 'less-engine' or 'less-servlet' to run though. Thinking this was just some Maven problems, I ignored this and built it myself with Eclipse, but then started running into problems with the @import statement not working, and also the reload never working even though the CSS file has been edited. So, I just tried to run 'mvn install' again, in case I built it wrong, and I now immediately see that the Maven errors were genuine problems:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.asual.lesscss.LessEngineTest
INFO : com.asual.lesscss.LessEngine - Initializing LESS Engine
INFO : com.asual.lesscss.LessEngine - The compilation of 'div { width: 1 + 1 }' took 32 ms.
INFO : com.asual.lesscss.LessEngine - The compilation of 'file:/D:/Development/DHTML/main/lesscss-engine/target/test-classes/META-INF/test.css' took 47 ms.
ERROR: com.asual.lesscss.LessEngine - Wrapped java.net.MalformedURLException: no protocol: import.css (/D:/Development/DHTML/main/lesscss-engine/target/classes/META-INF/engine.js#12)
ERROR: com.asual.lesscss.LessEngine - org.mozilla.javascript.WrappedException: Wrapped java.net.MalformedURLException: no protocol: import.css (/D:/Development/DHTML/main/lesscss-engine/target/classes/META-INF/engine.js#12)
Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.922 sec <<< FAILURE!
Results :
Tests in error:
compileToFile(com.asual.lesscss.LessEngineTest)
Tests run: 3, Failures: 0, Errors: 1, Skipped: 0
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.
Please refer to D:\Development\DHTML\main\lesscss-engine\target\surefire-reports for the individual test results.
Any ideas why this might be happenning?
Thanks in advance, Dominic.
It seems that there is a problem with the @import code on Windows. I will investigate it in the next few days.
The reload is not working because by default the library settings are optimized for production. The servlet can be configured using init parameters or JNDI. Check the ResourceServlet source and see how the "cache" and "compress" properties are initialized.
I finnally got a chance to look into this again. I'm not going to be able to test it till tomorrow morning, but I finally got both the maven builds to pass by changing this line in 'engine.js':
var result, charset = 'UTF-8', dirname = file.replace(/[^\/]+$/, '');
to this instead:
var result, charset = 'UTF-8', dirname = file.replace(/[^\/\\]+$/, '');
Will let you know tomorrow if there are any further problems.
Sorry, I patched this yesterday but didn't mentioned it here. You can get the latest copy from GitHub.
Just a quick word to tell you that I've successfully integrated the latest Less for Java (the one using the next official Javascript implementation of LESS) into a new Grails plug-in:
http://davidmarquis.posterous.com/introducing-less-css-plug-in-for-grails
Cheers!
David
Quick note to say I've integrated lesscss-engine into a plugin [1] for Scala's [2] Simple Build Tool [3].
I ran into one issue. I'm working with version 1.1.3 of Less CSS in my apps and your master branch on Github contains version 1.0.43. There's a different mechanism for escaping fragments of raw CSS that means I can't downgrade at this point.
To work around this I forked lesscss-engine to my own Github repo and published the fork on our repo server at Untyped (repo.untyped.com, lesscss-engine version 1.1.3).
It would be useful to see first party versions of lesscss-engine for a couple of key versions of Less CSS (suggest 1.0.x and 1.1.x). Would you be willing to create a couple of tags or branches on Github and push the artefacts to your Maven repo?
Best regards and keep up the great work,
-- Dave
[1]: https://github.com/davegurnell/sbt-less
[2]: http://www.scala-lang.org/
[3]: https://github.com/harrah/xsbt/wiki
I'd like then to deploy it on maven central repo, but I've seen that the github version is newer than the version on maven main repo, and it also have a minor version.
Could you please deploy your plugin in maven repo please?
thanks,
kiuma
ps.: I could also give you the mojo plugin (so that we have not too many sources sparse!)
Thanks, Dave! I'll update the project once I find some time available.
@kiuma
The version difference comes from the fact that LESS was first developed in Ruby and the JavaScript port was initially marketed as v2.0. The project was later renamed to less.js and the versioning started again from v1.0. The most relevant artifacts are currently hosted on our Maven repo. When I find some time I will submit them for inclusion in the main repository.
I've nearly completed my maven plugin. I'll soon put it under codehause and I need less.js be available without a custom repo.
Could you please submit the plugin ?
1) If you can't submit it may I fork it (put souce code inside the plugin) while the plugin is not available
2) If you prefer I can give you my plugin, at the only condition that you keep it OS. I don't mind for package naming.
Cheers,
kiuma
I am trying to incorporate your Less engine into JSF as a resourcehandler and as a custom component. At the moment I am a little stuck on how to get the @import working when the css is compiled server side. How could the imported css be retrieved from the JSF resources/css location and included as well?
If you need extra information or explanation, just let me know. Thanks for the Less Engine!
Can you please send me a GitHub message with the exact problems/errors you're facing.
java -jar lesscss-engine-1.3.0-SNAPSHOT-cli.jar myCss.less myCss-min.css -compress
the program just stays there without producing the output, not exits. Am i doing something wrong?
At the end of the day, i want to be able to create an ant task to do this compiliation. Do you have any examples or doc reference?
Thanks.
Thanks! It should be fixed now.