The interesting and thought-provoking “Is TDD Dead?” debates, and some explanations and examples of TDD that I’ve seen since then, have reminded me of something that came up whilst studying Computer Science at university (in the days long before TDD).

A few of my fellow students would develop programs by starting with the hardest parts of the problem, but the majority would always start with the easiest parts (obvious edge cases, validating input, “boilerplate” code etc).

In general:

The “hardest first” programmers wanted to crack the heart of the problem and eliminate risks and unknowns before bothering with the more straightforward work. They’d start out by just thinking, and wouldn’t worry about not yet writing any code. They were confident they could get the easier stuff done in due course, but didn’t see any point doing it unless and until they’d solved the main problem. They also didn’t want to be burdened or constrained by existing code when tackling the difficult bits.

The “easiest first” programmers wanted to start making progress and to immediately feel that they were getting somewhere and weren’t “stuck”. Having “momentum” and seeing progress helped them to continue. They’d generally start hacking something out without particularly worrying about it, and then fiddle with it until it seemed to work, whilst deferring anything that looked difficult until later. They felt the hard parts would be easier to tackle once everything else was already in place, even if some existing code would then need revising. At the very worst, if they did get stuck they’d at least have some code already written.

One of the lecturers noticed this, and the class ended up explicitly discussing it. When questioned, a few of us with previous programming experience generally favoured “hardest first”, but most of the rest thought “easiest first” was the best approach – and still thought that after discussing it. Notably, each group regarded the other approach as a horrible way of doing things.

At the time I assumed this was simply due to most of the students being new to programming, understandably struggling to get to grips with it all, and lacking experience with non-trivial problems.

However, much of the advocacy and explanation of test-first, test-driven development that I’ve seen has struck me as sounding remarkably like the sorts of things that the “easiest first” students might say. Listen, for example, to Kent Beck’s initial explanation of TDD’s origins and how it suited his personality at about 7:10-8:15 in the first “Is TDD Dead?” discussion.

Similarly, whilst I’m not particularly against TDD (and am happy to do it where it seems appropriate, or where it’s how a team is doing things), I do have some doubts and skepticism about test-first, test-driven TDD, and I now think this might reflect my own “hardest first” tendency. Even when doing TDD I often feel I’d have more quickly reached a better design if I’d tackled the “hard” problem of code and design directly instead of having to be led to the code piecemeal through tests and refactoring. Some of David Heinemeier Hansson‘s views in the “Is TDD Dead?” debates also sound rather like this to me.

So I’m starting to think that “test first” and “test driven” is perhaps most natural and beneficial for those who tend to be “easiest first” programmers, but can seem unnatural and unconvincing to those who tend to be “hardest first” programmers. In turn, the almost universal adoption of TDD that I see in local start-ups and job ads strikes me as implying that the “easiest first” viewpoint is now somewhat of an industry standard.

Perhaps most people are just intrinsically “easiest first” – at least to start with, and in the absence of any training to the contrary or when left to their own devices. Practices that work well for “easiest first” people are then perhaps a better industry-wide solution than anything that needs a “hardest first” mindset. I suspect this is now self-perpetuating, given the extent to which TDD is both advocated and demanded.

My only worry is that we’re perhaps denigrating and discouraging anyone that doesn’t fit that mould (especially if that might be me!).

I do hope we’ve not reached the point where it’s automatically seen as wrong to stop and think instead of diving straight into writing a test for some “simple” case.

Share this:

Like this:

Alongside ObMimic and various other tasks, I do some occassional “freelance”-type work. This tends to be quite varied, but is typically things that need a skilled Java developer but aren’t the core “development” work for a project (things like code reviews, investigating and fixing long-standing but low-priority bugs, cleaning up existing code bases against FindBugs etc).

One recent request was to write the Javadoc for an existing body of code (which had a few unit tests, but no existing Javadoc or other documentation). I was rather surprised that anyone would outsource such work, but in retrospect it made a great deal of sense for the particular project involved.

I’m now wondering whether this is a more widespread practice, and whether anybody has any particular views or experiences with outsourcing of Javadoc that they might like to share (from either side of the fence).

Personally, I’ve come to regard Javadoc, code and tests as needing to be developed together and feeding off each other. The Javadoc then acts not only as documentation for users of the code, but also as a specification that the code has to conform to – with the tests checking this.

I’m also used to writing Javadoc that has to be of “publishable” quality (in particular, because having comprehensive, detailed and precise Javadoc is a critical part of my own ObMimic product).

So it initially struck me as rather strange that someone would want an outsider to step in and write their Javadoc retrospectively.

However, as a result of this work I can see several reasons why this can be a good idea in some circumstances:

In this particular case, the client involved can communicate reasonably well in English but it isn’t their native language. They weren’t confident of being able to write sufficiently clear Javadoc in English, so wanted it done by a native English speaker.

Writing useful and accurate Javadoc is a quite different skill from developing and testing code. Not all developers are good at it, and not everyone is happy to do it. Even where developers do write Javadoc, it doesn’t seem uncommon for this to be rushed and left somewhat crude and incomplete.

Writing and proof-reading Javadoc can be very time-consuming, and can be somewhat of a distraction when one is busy developing code and tests. Where Javadoc is going to be needed for public consumption or future reference but isn’t particularly necessary for the development process itself, it might be more efficient to free developers from the burden of having to write Javadoc alongside everything else, and instead tackle it entirely separately.

Whilst large organisations might be able to dedicate appropriate people to writing Javadoc, this isn’t always feasible or cost-effective. Arguably, if someone has the skills to sufficiently analyse and understand the code and also to produce good quality documentation, they are probably too valuable to be spending their time writing Javadoc.

An external, independent person can write the Javadoc free from any pre-existing knowledge or assumptions that might be taken for granted by the code’s developers, and can more easily take the viewpoint of a typical user of the code.

Having an outsider work backwards from the code to produce detailed Javadoc can provide a useful code review at the same time, and can perhaps spot some types of mistakes and oversights that might go unnoticed during normal code reviews.

On the other hand:

I still tend to think that the ideal – when possible and cost-effective – is for developers to write their own high-quality Javadoc as an intrinsic part of writing each piece of code and its accompanying tests.

Outsourcing the Javadoc presumes that the relevant source code can be made available, which may raise security and/or legal issues.

It can be quite difficult and slow to take existing code and fully investigate and determine its actual behaviour, discern its overall intent, and then write suitable explanations, guidance etc.

To a large extent the effort involved and the quality of the results depends heavily on the nature and quality of the code; if the code is a mess of meaningless names and illogical design and behaviour, it’s going to be incredibly hard for anyone to derive accurate and logical Javadoc from it.

Even if the writing of Javadoc is outsourced, this will inevitably require some degree of communication, discussion etc (e.g. to settle on what degree of detail is required, resolve questions about the code’s intent or possible bugs etc). At the very minimum, somebody will at least need to check the results.

Writing Javadoc isn’t usually a once-only exercise; if writing the Javadoc is outsourced, who updates it when the code is subsequently changed?

For small projects, a single person might be able to write a full set of Javadoc in a reasonable timeframe; but for larger projects the amount of work involved might require multiple people or a prolonged effort. Beyond a certain size outsourcing this work might simply not be practical or worthwhile.

Obviously, the need for Javadoc and the quality of Javadoc required depends on the project. For example, for a closed-source Java library the Javadoc might be the only thing a user of the library has to go on, whereas for an open-source library they can always fall back to looking directly at the code; and for purely “in-house” applications and non-“library” code maybe there’s no need for Javadoc at all.

Similarly, the practicalities, relative costs and other pros and cons of outsourcing Javadoc will differ between projects and circumstances, and various trade-offs are always possible. For example, sometimes it might make sense to draft basic or outline Javadoc in-house and then use somebody else to just review, improve and finish it.

With regard to cost, I imagine there are no end of people around the world that could offer to write Javadoc at a low price. However, it seems to me that below a certain level of skill and quality there’s no point writing Javadoc at all, and that quite a high degree of programming, analysis and documentation skills are required before it becomes worth doing (and as noted above, the author’s language skills can also be relevant). Conversely, I imagine that using “high-end” consultancies or software houses for such work could be excessively expensive.

Is there a sweet spot somewhere between those extremes for relatively high-skilled freelancers? Perhaps the ideal is a freelancer with all the necessary skills but charging less than the full cost of using your own in-house developers. But are there many suitably skilled people available and willing to do such work – aren’t most such people in full-time jobs, or loathe to take on such relatively laborious tasks?

Overall, I’m curious as to whether outsourcing the writing of Javadoc is relatively common or unusual, and whether there’s any broader demand for such work. Does anybody have any views or experience of this? Is there anyone out there actually doing this as “freelance” work? Is there anyone who has tried outsourcing such work, and if so how did it go?

Like this:

ObMimic is a library of ready-made test-doubles for the Servlet API. It provides fully-configurable plain-Java implementations of Servlet API objects for use in out-of-container testing of any code that depends on the Servlet API (including, for example, JSF pages).

You can use ObMimic to write comprehensive, detailed tests for such code, using the same tools and techniques as for normal plain-Java code – without having to deploy and run your code inside a servlet container, and without having to write your own stubs or use general-purpose mocks that rely on your own assumptions about the Servlet API’s behaviour.

Fix to session handling: A bug in session-handling during RequestDispatcher “forwards” and “includes” has been fixed (see 16Bugs Bug #5 for details).

HttpServletResponseMimic.setStatus(int): By default this no longer clears the response buffer as was specified incorrectly by the Javadoc of Servlet API versions prior to 3.0 (but a new ServletContainerBehaviour option has also been added to allow explicit control over this).

As before, the free “Community Edition” and a free (but time-limited) licence-key file for evaluation of the “Professional Edition” facilities are available for download from the ObMimic website’s Downloads / Current Release page.

In addition, “Professional Edition” licence-key files and the “Enterprise Edition” can now be purchased via the website’s Buy ObMimic Licences page.

For full details and documentation please see the ObMimic website at www.openbrace.com.

Testing of JSF pages: A “how to” guide has been added to cover testing of JSF pages, based on experiments that have demonstrated that ObMimic can be used for out-of-container testing of complete JSF pages (including full control over the ServletContext and ability to access the JSF FacesContext and API within tests).

Maven: A “how to” guide and “pom.xml” file have been added to aid in the use of ObMimic within Maven-based projects.

Listeners for Servlet API calls: Listeners can now be installed into Mimics to intercept, examine and optionally modify Servlet API calls and their results at the point where they occur, as described in an accompanying “how to” guide. In particular, this can be used as a last resort to work around any questionable Servlet API calls made by third-party code, or to overrule ObMimic’s built-in behaviour for a particular Servlet API call.

Additional changes include:

Any attempt to use a Java EE jar that is deliberately limited to “compile-time only” is now explicitly checked for and reported, and documentation has been updated accordingly.

Options have been added for configuring how the ServletContext “getResource” and “getResourceAsStream” methods behave when given “directory” paths.

Various minor fixes and documentation improvements.

ObMimic has been tested against some additional JDKs, including a JDK 8 early-access release.

2 Background

This isn’t a comprehensive examination of the JDKs themselves, but just tests that:

The ObMimic code all works correctly on all of the JDKs.

The Ant build script delivered as part of ObMimic’s “Enterprise Edition” can successfully build ObMimic from its source code on the Java SE 7 and higher JDKs (including running its tests and generating its Javadoc).

The deliverables produced by the “Enterprise Edition” build script do themselves work correctly on all of the JDKs.

The only significant changes since that earlier post are that the tests are now run on 64-bit systems (with the Linux system now being Ubuntu 12.10); and the ObMimic “Enterprise Edition” build script is limited to Java SE 7 or higher (as it now needs Servlet 3.1, which in turn requires Java SE 7 or higher).

3 Issues Encountered

The issues encountered on the newly-added JDKs were as follows:

3.1 IBM Java SE 6 Logger doesn’t successfully look-up message keys

The java.util.logging.Logger methods that take a “msg” argument are supposed to accept a message key and look it up in a ResourceBundle to translate it into the actual message to be used (substituting given parameters into the message where applicable). This is supposed to follow the usual rules for finding the most relevant localization of the resource bundle.

There’s one ObMimic test case that relies on this, as it’s testing that a custom Handler correctly processes calls that use a message key. This test case works on all other JDKs, including IBM Java SE 5 and 7, but on IBM Java SE 6 it fails – the message key is written to the log “as is” rather than being converted into the full message from the resource bundle.

I’ve not found any definitive explanation or bug report for this, but there is a comment from “tripl3des” within a Can’t find bundle… post in an IBM discussion forum that says

“ResourceBundle implementation for IBM JDK does not respect the contract described in the API. At least not for 1.6 version…. IBM JDK only works when there is a file for the exact locale requested.”

If true, that sounds similar to what I’m encountering here (though there are other types of message look-ups throughout ObMimic that are working correctly).

The test case that fails isn’t critical to ObMimic (it’s just part of the full testing of an optional feature in some “common” code that’s bundled with ObMimic); there doesn’t appear to be anything wrong with the source code; and it all works OK on all the other JDKs.

At any rate, unless and until I learn any different I’m assuming this is just a bug in this particular JDK – and that anybody using this JDK’s java.util.logging facilities will encounter this in any logging with message keys, not just if they happen to do such logging whilst using the custom “handler” that I’m testing.

So whilst I don’t like having JDK-specific tests, in this particular case I’ve decided the most appropriate solution is to just skip this one specific test when running on IBM Java SE 6.

3.2 IBM Java SE 6 and 7 bootclasspath is more complex than just “rt.jar”

Until now, ObMimic’s “Enterprise Edition” build script has been explicitly specifying a “bootclasspath” that points to the /jre/lib/rt.jar of the JDK it’s using..

This has been done because the build’s default settings specify Java 5 as the “source” and “target” level, and javac issues a warning if these aren’t accompanied by an explicit “bootclasspath”. Explicitly supplying the “bootclasspath” doesn’t really achieve anything other than cutting out the warning message, as the build with default settings doesn’t know of any JDK other than the one it’s running on and can only specify that JDK’s own boot classes. But under the circumstances the warning is superfluous and distracting, and seemed worth cutting out.

Unfortunately, the IBM JDKs for Java 6 and 7 need more than just “rt.jar”. Some of the core Java classes (including, for example, java.lang.String) are in a separate “vm.jar”. To make matters worse, this is in different locations in IBM JDK 6 and IBM JDK 7. Then there are other necessary classes in other jars within the /jre/lib directory structure.

As a result, javac and javadoc on the IBM JDKs seem to work OK when it’s left to its own devices, but once an explicit bootclasspath is given they seem to need lots of jars from various locations within /jre/lib.

There are VM options for adding specific jars into the default bootclasspath instead of completely replacing it, and one could always configure the bootclasspath to include any and all jars within the entire /jre/lib directory structure. However, I’m not sure enough of an appropriate way to set the bootclasspath that will work for the IBM JDKs whilst also being entirely safe and appropriate for all other JDKs.

In the end I’ve modified the build script to not specify the bootclasspath at all. This re-introduces the warning message about it not being specified, but it works on all of the JDKs and is perhaps safer and more “truthful” than artificially suppressing the message.

In any case, the warning can always be avoided by changing the build properties that set the “source” and “target” levels if you don’t actually need compatibility with JDKs earlier than the one you’re building on.

3.3 Stricter Javadoc checking in JDK 8

Building the code on JDK 8 resulted in lots of Javadoc errors!

It turns out that by default Javadoc on JDK 8 carries out much stricter checking of the Javadoc content. This includes checking for incorrect HTML tags, characters that ought to be escaped/encoded, HTML attributes that are necessary for accessibility etc.

This appears to be a result of the “JDK Enhancement Proposal” JEP 172 DocLint.

In my case it found:

Quite a few “&” characters and a few “<” and “>” characters that needed escaping;

Numerous silly little mistakes in HTML tags (e.g. “<ul>” that should have been “</ul>”);

Some tables that were missing “summary” or “caption” attributes.

I can see this coming as a bit of a shock to many people when they switch to JDK 8 and suddenly discover that their builds fail with lots of Javadoc errors!

There’s apparently an “-Xdoclint” option that can be used to turn off some or all of the checks, but of course it makes more sense to actually fix the errors. If your Javadoc is otherwise reasonable there might be a large number of these errors, but each should be pretty trivial to fix.

It took me an hour or two to fix all of these Javadoc errors in the ObMimic code, but as always it feels good to have found and fixed these and to know that this is now checked by each Javadoc run.

3.4 A JDK 8 b99 Javadoc bug?

I also hit an apparent Javadoc bug on JDK 8 build b99 where it gives an error plus a warning for “@throws X” where “X” is a type parameter of the method (it looks like some of the Javadoc processing is taking the “X” as a class name rather than recognising it as the method’s type parameter).

However, there already seem to be JDK changes in progress that might be relevant. So for now I’m assuming this is just an early-access quirk that will get fixed in due course.

I’ve implemented a temporary (rather hacky!) work-around for the single ObMimic method affected by this, but it doesn’t seem worth going into any more detail here on the assumption that this will turn out to be a purely temporary issue.

Share this:

Like this:

Whilst using an installation of Eclipse 3.7.2, I found that it silently fails to show the Javadoc provided by my ObMimic library.

The Eclipse project was pointing at the right location for this Javadoc, but flatly refused to show any of it in pop-ups or the Javadoc view.

A look at the Eclipse logs showed a pile of “StringIndexOutOfBoundsException” crashes from Eclipse’s attempt to parse the individual Javadoc files. This turns out to be a known Eclipse bug, 394382, which is marked as fixed in Eclipse 4.3 M4 onwards.

The problem arises from a change in the “Content-Type” header within Javadoc files produced by JDK 7. Prior to JDK 7, these specified the “charset” as part of the content-type string, but from JDK 7 onwards the “charset” is given by a separate attribute.

The Eclipse code that fails is trying to extract the charset’s value from this line (i.e. the “UTF-8″), but it crashes when given the newer form of the header.

Obviously one solution would be to insist on Eclipse 4.3 M4 or higher, but ideally I’d like my ObMimic Javadoc to be usable on any reasonable version of Eclipse that any user might have. For the time being that ought to include 3.7.x versions. Most of all I don’t want people complaining about my Javadoc not working when it’s actually an Eclipse bug!

So as a work-around for this I’ve added a step into ObMimic’s build script to change this particular header back to its old format. As far as I know both formats of the header are valid, and there doesn’t seem to be any pressing need to use the newer format, so it seems harmless to use the older format for this header.

To achieve this, as soon as the relevant Ant script has generated the Javadoc it now uses the following “replace” task to change the relevant lines within all of the Javadoc’s HTML pages (where ${obmimic.javadoc.dir} is the root directory into which the Javadoc was generated):

Note that the above is based on the Javadoc charset being UTF-8 (from the Ant Javadoc task specifying “docencoding” and “charset” attributes of “UTF-8″), and would obviously need adjusting for any different charset or if making it variable. Also, the “summary” attribute produces a message showing how many replacements were carried out, to at least confirm that the replacments have taken place (without this, the replacement is done silently).

The main change from the previous 1.0-beta-8 release is compatibility with Servlet 3.1 and Java EE 7 libraries, so that ObMimic can be used with such libraries.

Whilst full support for Servlet 3.0 and 3.1 features is still pending (and intended for future releases), in the meantime this at least allows ObMimic to be used in the presence of Servlet 3.1 or Java EE 7 libraries (i.e. it can now be used with any Servlet 3.1 library as well as with any Servlet 2.4, 2.5 or 3.0 library as before). This also paves the way for the gradual introduction of Servlet 3.1 support in future releases.

In addition:

ObMimic’s Javadoc is now supplied in Java 7 style (but including an adjustment to work-around a problem in some versions of the Eclipse IDE that render Eclipse unable to parse such Javadoc).

Various minor fixes, revisions and improvements have been made to ObMimic’s documentation.