Thursday, June 25, 2009

30 slides about testing ajax components

Last Sun Open Community Forum is over, and like past events (the name changes, but people remains the same) it was the perfect opportunity to get the spanish java community together to enjoy some beer and - incidentally - to talk about software too :)


This year has been great. Due to my nemesis-agenda I could not be there for the second day, which means that I missed the groovy lab by Nacho Brito (if you are talking about groovy in Spain, that's Nacho) and Daniel "greeneyed" Lopez - seriously, I wanted to see him running five languages in the JVM during a 2-hour lab.

The ones that I managed to attend were great: Jorge Sanchez introduced some alternatives for large-scale integration and presented the new spanish MySQL community, and Alfredo Casado fired some great slides about content negotiation and all things REST.

We were also there: Sergi Almar had a really succesful lab about what's coming in Spring 3.0 which enjoyed some massive assistance. Due to lack of space, some people had to spend the entire lab with their laptops over their kneels but they still were not leaving. I delivered a brief (30-min) talk about how to mix progressive enhancement, java, and javascript tests.


Lots of other things to share, but that will be in a couple of weeks. Cheers!

Thursday, May 21, 2009

Loom 1.5 is out; are you doing something interesting today?

Today we are releasing Loom 1.5. This is our first release intended for public consumption, so if you are thinking about giving it a twirl we will be more than glad to help.

I am not going to talk about things included in this release, such as a YSlow! 'A' rate for the demo application (94 out of 100, yay!), the ImageValidation annotation or the simplified spring config. Instead, I wanted to comment something present since our 1.0 release.

Things that your web framework should be doing for you


Last entry was about how your javascript and server-side code should talk HTML at both sides, because generating javascript from the server is a bad practice. This one is about how you (and by "you" I mean your web framework) should be generating your HTML markup.

What follows is what we like to call a Contributed View, meaning that each piece of the web framework can contribute aspects to the generated HTML.

Form Fields


An integer field validated between 5 and 100 can contribute this to the generated HTML:



  • Converter: inject a 'number' css class to be used by javascript and CSS style sheets.
  • Validator: inject attributes (scale="0" min="5" max="100") to be used by javascript validations. Better yet, inject maxlength="3" to make the browser enforce the maximum length of this field. It can get tricky since you must take into consideration negative values and decimal point.
Notice what the server should not be generating: javascript code. You can still use prototype, jquery or dojo to validate user input, as the server side is just providing the required metadata.

Links




The easiest example of URL decoration affects links pointing to forbidden resources. If the application developer is using annotations to specify permissions (with JSR-250 @RolesAllowed, for example) the security interceptor can contribute an "unauthorized" css class to links and forms. Again, it is your responsibility as the application developer to use CSS or javascript to hide or disable them.

About our next few weeks


I have been seriously lectured by some friends about how we are not dedicating enough time to make visible the awesome things we are into these days. I hate sounding like a salesman, but people got so serious that I thought I should make an exception just for today:

We are an heterogeneous software company, which means that the PHP guy sits next to the java freak most of the time and we still somehow manage to keep the peace - most of the time. When we can choose, we have been using the Loom-Spring-Hibernate combo for almost two years and are quite happy with it. There are lots of cool details like the browser cache annotation that do not have an equivalent in other web frameworks.

If you test and like it, I want to know. If you test and find things that you don't like, hey, I still want to know!

About our last few weeks


Our training courses have been a great success! We are really proud of the feedback received, 80% of the attendees to both courses have given us the highest qualification possible. In our first Core Spring Course in Madrid, people with previous spring experience started learning something new from day 2, which is a remarkable achievement for an introductory course.

On a related note, a friend from Tenerife was quite pissed at me because he had to investigate a big deal to find our Agile Project Management Course Contents. It's more or less the same thing you can see in this blog, but four hours a day. Last week lots of people confessed that they were expecting to fall asleep in the middle of the course, but instead had lots of fun - and with 'we', I mean 'me included'.

On the "things to improve" comments, we have been asked to provide more practical examples for both courses. We are certainly looking forward to improve that.

Thursday, April 16, 2009

Guess who is the first SpringSource partner in Spain

Yep. We are.

These last weeks have been like playing the violin with one hand while running across a Super Bowl match - with the ball -, but results are finally here: we are quite excited to announce the partnership between Extrema Sistemas and SpringSource.
Concentrate in your training
This agreement is the conclusion of lots of work on both sides, notably Sergi Almar who started the whole thing in the first place. Extrema Sistemas will be delivering the SpringSource official courses in Spain, starting in Madrid on Apr 27-30 and later in Barcelona on May 25-28.

On a related note, I will be in Tenerife on May 4-8 to deliver our Agile Project Management Course on-site for a coalition of software development companies. It will be a full house, and as an interesting extra I will give a quick talk (well, "quick" be pronounced as "like two hours") at my former University.

I am really excited with the perspective of looking at my old college rooms from the other side :)

Monday, March 23, 2009

Start testing your Javascript server-less

Are you still launching tomcat to test your javascript code? You shouldn't.

When applying the MVC pattern, HTML as always been considered to be part of the View, which is only correct from a server point of view. In browser-land HTML is the Model, the Controller is our javascript code, and the View is - well, it can be your chrome, your CSS, whatever. The important thing is, there are two MVCs involved:



Two years ago we started applying some simple rules for javascript development:

  • No javascript code generated by the server. Nil. Zero. Nada. That would only make things harder to port and reuse. Instead, the server generates the HTML attributes (some standard and some not) to be used by javascript code. Combine this with progressive enhancement and you will have an almost functional interface to add your javascript icing.

  • Javascript is always tested using static HTML files, which represent the approved API between server and client software. You can test easily your javascript code, and the server only has to stick to this API.

  • Javascript unit testing may be added later. We use UnitTest, but there are others: JQuery, Firebug, TestMonkey... the list goes on. Notice that I am not considering Selenium here, as we are not testing interfaces but javascript code.





No matter the programming language, life is easier if you do not try to generate your Controller. Now your test environment can be 100% static.

These simple rules have made our lives so much easier. Instead of the classic mixup of technologies to test Ajax interfaces, there is just a javascript test engine and some html files to test things up (including some static JSON response examples). Before this, something like testing our validation code was a killing effort. This can still be integrated with ant or maven without requiring a java server in the middle.

Going static include some additional advantages:

  • You can interact with the interface by hand. When the tests are done, you still have a working HTML page to pick at.

  • You can trace and debug any failing assertion using Firebug or the IE debugger.

  • There is no roundtrip to the server. Things can only be fixed up to the HTML API, so there is no point in thinking in java at this point.



Think Divide-And-Conquer, but separating client from server using HTML. Once all javascript code is tested, you can start integrating things with the java server just by generating the expected HTML.

Monday, February 09, 2009

My Devoxx slides: 15 minutes about improving your users cache experience

I finally managed to save some time to upload my slides about the browser cache at Devoxx 2008, in what seems like a life ago (long story short, converting to Powerpoint XP back and forth is not a nice idea if you plan to upload it sometime later).

Most people missed it since it was scheduled as a quickie, which is fine since I'm a lame speaker (specially when throwing foreign languages into the mix). The slides were OK though, so I wanted to share. And here they are.



All in all, devoxx was an awesome experience. I'm looking forward to repeat this year!

Wednesday, November 26, 2008

Loom 1.0 final is out. Let there be AWESOME.


After two years of work, 700+ java classes, 400+ tests, 35 javascript test pages and a hell of a week polishing rough edges, we finally got the release out the door.

(I enjoy an entire night of pure insomnia once a month, which looking behind is a great boost for productivity :)

With lots of bottled awesomenesstm inside, the following is a selection of the new features that come included in Loom 1.0:

This release includes a scaffolding tool



We finally got tired of starting projects from scratch, so Rafa got a week dedicated to it and prepared a tool that can kick start a project in five minutes, assuming a decent internet connection. Just download scaffolding.zip from the download page, unzip and run:


# Create a project named myapp
scaffolding create myapp

# Create the eclipse project
# (requires GRADLE_HOME defined)
cd myapp
gradle eclipse

# Deploy on your favorite web server
# (requires CATALINA_HOME or JETTY_HOME defined)
gradle deploy-tomcat
gradle deploy-jetty


Sometimes gradle timeouts while waiting for maven repositories; in that case, just wait a little and repeat the command.

The created template will be based on gradle, which is (some artistic license, here) a combination of ivy + groovy + steroids. Notice that Loom does not use groovy but as a substitute for ant (and a great one at it!), the rest is 100% java.

Open the project using eclipse, where compiled java files go directly into WEB-INF/classes. Open "Run as" and select "myapp - run tomcat" or "myapp - run jetty" (again, CATALINA_HOME or JETTY_HOME are required). No plugins are needed, no build process, nothing. Just compile and open a browser at http://localhost:8080/myapp



Now, create a new JPA entity with some attributes using eclipse (Loom does not require JPA, but this is easier this way) and add your own CRUD interface:


# execute this in your project home dir after MyPersistentClass has been compiled
scaffolding crud com.acme.model.MyPersistentClass


That's it. Restart the server and test your interface. The form should validate your JPA constraints, which can be modified at any time without re-creating the interface or anything.

This release includes Javascript and CSS repositories



Your javascript and CSS files can be concatenated, minified and gzipped in production without involving any ant or maven script.

This is similar to what JAWR does, but easier to configure and use. Its main features are:

  • Configured using spring: it does not require external files.

  • All files (javascript, CSS, referenced images) can be loaded from the classpath, which means that they can be provided by other jars. You can still use images inside CSS files, and they will be served - even from the classpath.

  • All files (again - css, javascript AND image files!) are aggressively cached based on their MD5 checksums. If you have ever worked with GWT, you may be familiar with the concept - if not, drop by our Devoxx talk where we will be talking about this as long as time allows.

  • You can choose between YUICompressor (javascript and CSS) and JSMin (javascript) just by dropping them on the lib folder. They are included in the /lib/compressors folder of the Loom distribution.


This should be easier to digest using an example. The spring file:


<bean class="org.loom.resources.WebResourceBundleRepository">
<property name="bundles">
<bean class="org.loom.config.SpringResourceMapFactory">
<property name="resources">
<value>
css=/css/base.css /css/basemod.css
ie=/css/yaml-3.0.5/core/iehacks.css /css/my_iehacks.css
demo=classpath:/js/prototype/prototype-1.6.0.3.js classpath:/js/loom/core.js \
classpath:/js/loom/format.js
</value>
</property>
</bean>
</property>


The JSP file:

<l:css resource="css"/>
<l:css resource="ie" ie="any"/>
<l:script resource="demo"/>


The generated html with config.development=true:

<link href="/myapp/resources/css/0/2008a6c2ba1c6009f5f84db99e6a76e0/base.css" rel="stylesheet" type="text/css"></link>
<link href="/myapp/resources/css/1/f6c4b21a2f6c9d265d14081243c2da40/basemod.css" rel="stylesheet" type="text/css"></link>

<!--[if IE]>
<link href="/myapp/resources/ie/0/658801c193faa8e7173e2cd220093e67/iehacks.css" rel="stylesheet" type="text/css"></link>
<link href="/myapp/resources/ie/1/658801c193faa8e7173e2cd220093e67/my_iehacks.css" rel="stylesheet" type="text/css"></link>
<![endif]-->

<script src="/myapp/resources/demo/0/b5684120e496c310977713be34be4868/prototype-1.6.0.3.js" type="text/javascript"></script>
<script src="/myapp/resources/demo/1/07139c2fd5d77ee9fa619ff335996068/core.js" type="text/javascript"></script>
<script src="/myapp/resources/demo/2/bd7026fb11a52e8fe8c671e894885e78/format.js" type="text/javascript"></script>



The generated html with config.development=false:

<link href="/myapp/resources/css/all/7c66dcfb53bb87201e74aef4f1211a63/" rel="stylesheet" type="text/css"></link>

<!--[if IE]>
<link href="/myapp/resources/ie/all/da188973e7712595d03da0bbbfa059f4/" rel="stylesheet" type="text/css"></link>
<![endif]-->

<script src="/myapp/resources/demo/all/1c004c851402d83a84e3d7a2fb73a375/" type="text/javascript"></script>


The same page, with development=false

These resources have been automatically concatenated, gzipped, MD5-hashed (just once!) and set to expire ten years from now. The browser will never ask for them again, as long as they do not get modified or the user hits the "refresh" button. During normal navigation only the html file will be retrieved.

But there's more: during development, your changes will be detected on real time, but the browser will only ask for the resources that have changed. The typical 304 traffic between server and client will just not happen.

Go test the feature live on the new demo, just turn on / off the debug switch (at the top right corner) and open firebug to see the number of files involved for each request. Now, navigate between pages and keep an eye on your firebug net tab. No files are being requested.

Wait, there's more.

This release includes partial JAX-RS support



We have added support for the mapping annotations of the JAX-RS spec. In fact, the CRUD interface created by scaffolding does just that:


public class MortgagesAction extends AbstractAction {

@RetrieveEntity(on={"save", "edit"})
private Mortgage mortgage;

@GET @Path("/")
public Resolution list() { ... }

@GET @Path("create")
public Resolution create() { ... }

@GET @Path("/{mortgage.id}")
public Resolution edit() { ... }

@POST @Path("/{mortgage.id?}")
public Resolution save() { ... }

@DELETE @Path("/{mortgage.id?}")
public Resolution delete() { ... }

}


Combine with JavaRebel to enjoy The Extra Cool Development Experience. Open your Action, modify your mappings, refresh the browser - and only your Action class gets reloaded. New Actions cannot be added on-the-fly and there are other limitations, but this first release is really promising.

This release includes some serious pagination components.



I have tested almost every pagination solution in the wild since 1999, checking them off with my old list of (almost) reasonable requirements:

  • Pagination should be done by the database if possible. Having said that, sometimes I don't have a database, and the web framework should do its work.

  • There is almost no difference between a paged list (<ul>) and a paged table (<table>).

  • Pagination and sorting should be transparent, or almost. That is tricky when it involves the database.

  • It should include a professional look and feel by default. This is not my merit, kudos go to Antonio Lupetti.



<l:pagedTable data="${action.mortgages}" id="mortgages">
<l:column sortable="false">
<l:inputCheckbox name="selectedRows" class="selectRow checkbox" value="${row.id}" renderLabel="false"/>
</l:column>
<l:column property="id" />
<l:column property="name" action="Mortgages" event="edit">
<l:param name="mortgage.id" value="${row.id}"/>
</l:column>
<l:column property="address" />
<l:column property="principalLoanBalance" title="Loan" />
<l:column property="creationDate" class="date" />
</l:pagedTable>




Again, you can check examples with tables and lists in the demo application.

This release includes LocaleAwareException and HttpException



This is just a pet feature, but I love it. You can throw exceptions that will get to the user as any normal input validation errors, or throw HTTP errors like 404 at any point of the code. It's handy.

This release includes extensibility



Two years are a lot of time, in framework years. We kept the original goal of a lightweight and focused web framework, and moved all the server and javascript components that started cropping everywhere to the addons project (take it easy - it's not that mature yet).

The point is not about the addons project but about this whole new approach to extensibility: just drop a META-INF/loom-descriptor.properties in your jar file like this:


# The list of annotation processors provided by this jar
annotation-processors=org.loom.addons.multiupload.MultiUploadAnnotationProcessor, \
org.loom.addons.confirmation.RequiresConfirmationAnnotationProcessor, \

# The list of Converter factories provided by this jar
converter-factories=org.loom.addons.autocompleter.AutocompletedConverterFactory

# The list of messages locations provided by this jar
messages=classpath:resources/addons-messages


Loom will load it from the classpath and the application developer may use its contents:

  • Java annotations

  • Validators and Converters

  • Javascript components, including CSS and image files

  • Internationalized messages


And, of course, its own JSP tags as usual.

And that's it?



Damn, no. This is the framework we are using to build applications, every day. We expect it to keep growing with a steady pace with all the know-how in our way for years to come.

I only wish "steady" could mean "slower" in this context. I can live without the stress of the last few weeks :)

Thursday, October 30, 2008

My top list of java tools

A thousand spoons when all I need is a keyboard

Lack of imagination is one of our worst sins as software developers. We do the same things over and over again, but we rarely modify our ways - me at least. After some years, these are the tools that made it into my tricks box for everyday tasks. Tiresome operations are not my thing.

Chances are you are already using at least some of these, but here we go anyways:

StringUtils



The bread and butter of the commons-lang library, this utility class includes some methods that should seriously have been included in String long time ago.


StringUtils.isEmpty(null) && StringUtils.isEmpty(""); // true
StringUtils.isBlank(" \n\t"); // true
StringUtils.substringAfterLast("foo.bar.baz", "."); // "baz"
StringUtils.substringBeforeLast("foo.bar.baz", "."); // "foo.bar"
StringUtils.split("foo.bar.baz", '.'); // { "foo", "bar", "baz" }
StringUtils.split("foo, bar,baz", ", "); // { "foo", "bar", "baz" }
StringUtils.leftPad("1", 3, '0'); // "001"


IOUtils and FileUtils



A must-have for the rare occasions where you need to manipulate files by hand. Both are pretty much alike (FileUtils for File, IOUtils for InputStream and Reader classes) and come bundled in commons-io.


File file1;
File file2;
InputStream inputStream;
OutputStream outputStream;

// copy one file into another
FileUtils.copyFile(file1, file2);
IOUtils.copy(inputStream, outputStream);

// read a file into a String
String s1 = FileUtils.readFileToString(file1);
String s2 = IOUtils.toString(inputStream);

// read a file into a list of Strings, one item per line
List<String> l1 = FileUtils.readLines(file1);
List<String> l2 = IOUtils.readLines(inputStream);

// put this in your finally() clause after manipulating streams
IOUtils.closeQuietly(inputStream);

// return the list of xml and text files in the specified folder and any subfolders
Collection<File> c1 = FileUtils.listFiles(file1, { "xml", "txt" }, true);

// copy one folder and its contents into another
FileUtils.copyDirectoryToDirectory(file1, file2);

// delete one folder and its contents
FileUtils.deleteDirectory(file1);


Google collections



This is the best implementation of a collections extension that I know of. Some of these are shouting to be included in the JDK:


// create an ArrayList with three arguments
List<String> list = Lists.newArrayList("foo", "bar", "baz");

// notice that there is no generics or class cast,
// and still this line does not generate a warning.
Set<String> s = Sets.newConcurrentHashSet();

// intersect and union are basic features of a Set, if you ask me
Set<String> s = Sets.intersect(s1, s2);

// Example of multiple values in a Map
ListMultimap<String, Validator> validators = new ArrayListMultimap<String, Validator>();
validators.put("save", new RequiredValidator());
validators.put("save", new StringValidator());
validators.put("delete", new NumberValidator());

validators.get("save"); // { RequiredValidator, StringValidator }
validators.get("foo"); // empty List (not null)
validators.values(); // { RequiredValidator, StringValidator, NumberValidator }


java.util.concurrent



Not everybody needs the heavy lifting of java.util.concurrent, but the concurrent collections are handy:


// a map that may be modified (by the same or different thread) while being iterated
Map<String, Something> repository = new ConcurrentHashMap<String, Something>();

// same with lists. This one is only available with Java 6
List<Something> list = new CopyOnWriteArrayList<Something>();


Hardly a large toolbox, is it? If your favourite library is missing, feel free to add it :)

I WILL BE AT DEVOXX!! I have a 15 minute talk about the browser cache on December 10th. I am really excited about this, this will be my first JavaPolis (now Devoxx) experience.

It will be fun, I plan to talk about 304, Expires / Cache-control, and maybe have a small demo of MD5-based cache if time permits. If you happen to be there, please drop by and say hi!

Tuesday, October 14, 2008

"Practical API Design", the book

still learning!
It got mentioned on the last OpenJavaDay (thanks Ibon!) with such a good review that I got my own copy of Practical API Design by Jaroslav Tulach. The book describes the set of standards developed by the Netbeans team during the last ten years, from framework novices to their current state of maturity.

Even if you don't agree with some of the book recommendations (which is ok, since they aim at being a bit controversial) it is still a complete source of good practices when designing - not an application, but - a platform. If your case is not as much about "design" but "design while ignoring how many people are using your API and which parts are found useful", this book is a must-read.

If I had to complain about something, it spends too much time in the introduction chapters. It sets the foundation stone of good API design and I really needed to grab some perspective about API stability over time, but a bit shorter would have made it perfect.

I love the freshness in the style, the way it seems to be designed with my case in mind. A quote after several pages describing its intended audience:

If you are still asking yourself wether you should read the book or not, there is a much shorter answer: "Yes, you should read this book!"

Indeed :)

Wednesday, October 08, 2008

The coolest prototype calendar ever

Roberto has been doing amazing things with calendars these days. With current loom trunk, this java attribute:


@Temporal(TemporalType.TIMESTAMP)
@DateValidation(minValue="today + 1d", maxValue="today + 1y")
private Date start;


With this javascript code:

// create calendar
$$('input.date, input.dateTime').each( loom.ui.createCalendar, {});


Renders this absolute piece of awesomeness:


  • Dates before today and after one year (from today) are disabled, as specified by @DateValidation. As always, the server side will use the same constraints.

  • The use of @Temporal (the standard JPA annotation) triggers the interface to ask for date and time. The default would only ask for a date.

  • It uses the same attributes (min, max) and format (ISO-8601) specified by the HTML 5 draft, which should help replacing it when browser support arrives by 2025 :)

  • Full implementation of the PHP strftime format.


Other use cases may be tested here, as the javascript library can be used standalone without loom.

MY PRECIOUSSSSSSSSS...

UPDATE: The calendar has been included in the 1.0 release. Just download the jar file, uncompress, and look inside the js folder.
UPDATE 2: As of loom 1.1 we have added a loom-javascript.zip file which includes just the javascript and css files. To use it, just take a look at the included html test files. They are not pretty, but should indicate a clear way to use the components.

Thursday, September 25, 2008

My take on the SpringSource license change

I have real problems getting what all this fuss is about:
  • There is a global economic crisis, in case you didn't notice. It affects SpringSource as much as anyone else.

  • They do numbers. They notice that a big share of their costs are related to maintaining legacy versions for non-paying customers.

  • They react to minimize impact, while still being open.

I DON'T HAVE THEIR NUMBERS. I cannot have an opinion about if this is a good move or not. Neither do any of you. Please stop saying how you would react if you were the boss of a multimillion dollar company and had to face an unknown problem: "Oh, I would stay on top of the Titanic seeing everything sinking in all its glory, but would not move an inch away from openness", or "I would change the business model and put more stress on training and consulting - no, I don't have a clue about how much they make from consulting, is that important?"

It's funny how most people agree that they wouldn't do a better job developing a java integration framework, but they do know better when talking about management. I frankly prefer this move than some kind of Lehman Brothers thing happening to a framework that is at the core of all the systems I have designed in the last few years.

I am only posting this because dissatisfied customers are 4x more visible, and I don't think it's fair to the good work these guys are doing.