Goodbye Sun
Tomorrow is my last day at Sun. I can't help to feel a little weary after all these years. I'm leaving behind a wonderful company, and a tremendous number of smart colleagues.
Bye bye
( Feb 27 2006, 10:07:00 PM CET ) Permalink Comments [1]Moving to WordPress
This is just to inform you that I will move my blog to another location, so you may want to update your links.
( Jan 13 2006, 10:24:47 AM CET ) PermalinkThousand words say more than a single picture
In my spare time, I have begun to work on a solution for yet another itch I have had for years. One of my recent involvements in a greenfield software development project brought it all back again.
I had been working on a framework, and had basically already put some abstractions (Java classes and interfaces) together to guide the discussion, put my head around it, and prototype some of the things I had in mind. In fact, a lot of things were already tested, and everything seemed to be working just fine.
Then people started to ask my for detailed class diagrams. Now, don't get my wrong. I like UML. I like modelling. In fact, I already created a couple of UML diagrams to explain some of the relevant abstractions. But in most of those circumstances, I leave a lot of detail out. I don't list all of the attributes and I don't list any of the methods on the class. So although the UML is precise, it leaves out a lot of the details.
Anyhow, after some evasive manoeuvres, I ended up using a tool to reverse engineer all of my sources into a diagram, knowing that this diagram would be invalidated the moment that people would work on the code. And I have to say, it looked impressive: lots of classes, lots of interfaces, lots of associations, lots of attributes, lots of operations. The only thing that it didn't do is help you to understand how things fitted together.
So here is my problem: what is the point of having class diagrames knowing that they will be invalid as soon as somebody touches the code, and what would minimally need to go into a Java source based class diagram to be helpful at all.
A related question is if pictures really say more than a thousand words, in all circumstances. If you want to express the exact same thing, then you need very complicated pictures to express all of that. The reverse is also true. Simple pictures can easily be explained in less than thousand words.
In reality, in a lot of the situations, just listing the attributes and methods do not add any semantics at all. People may think that it explains something, whereas in reality, it is just interpretation: listing an operation called calculate() could mean anything, ranging from calculating the size of a JFrame to calculating the 10^10 number in pi. In fact - and this may surprise you - it does not even need to involve any calculation at all. The operation calculate() might start 'Super Mario Bross' for all I care.
So, generally speaking, having detailed class diagrams still require a lot of words (possibly thousands) to explain what it means.
Anyhow, I suspect that people will not always agree with my opinions, so in order to prevent me from waisting valuable time to frequently reverse engineer code, I thought I would make my life a little easier, and to create something that would generate class diagrams from my sources automatically, as part of the project build cycle.
I suspect this will take my quite a while, so I will probably blog about this more often. For now, it may be interesting to show some examples of what I am able to do today:
This is just one of the pictures generated from the sources from the piece of software itself. You may notice that it leaves a lot of stuff out. (On purpose.) At this stage, I intend to have it eventually included in my JavaDoc, so I there is one central class for every diagram. For that class, I list all of the attributes and methods. Notice that I am also deliberately leave out the package names for related classes: adding the package names would make it impossible to read. (You would end up with diagrams with more than a thousand words. I hope you see why that would be a problem.)
( Jan 08 2006, 09:01:15 PM CET ) Permalink
Maven 2.0 Support for NetBeans
Dear Eclipse user. Have you ever felt annoyed by the fact that there is no official support for running Maven 2.0 from your IDE? In that case, you might find it interesting that there is an easy way out: switch to NetBeans. I am happy to announce that - as of yesterday night - the NetBeans community has the ability to run Maven 2.0 from NetBeans directly. Additionally we can start Continuum from NetBeans. And we have very sensitive tag and content completion for POMs.
Thanks Milos!
( Jan 04 2006, 07:07:33 AM CET ) PermalinkNiks Relatief (Nothing Relative At All)
This summer, during the holidays, I read a great book on formal languages. It had been quite some time since I read something as fundamental as that, but after I got a taste of it, I find it hard to let go. So for this holiday, I added some semi-scientific literature to my wishlist.
The book that I ended up reading is called "Niks Relatief" - Dutch for "Nothing Relative At All" - by Vincent Icke. From the title, it might not be that obvious, but it is about relativity theory. Definitely interesting. It exists of two parts: the first part does not contain any formulas, and explains classical mechanics and quantum mechanics in general. The other part of the book explains the math behind all of it.
I never really enjoyed physics so much, partly because I almost electrocuted my sister when I was nine, thinking I had it all under control, and partly because it seemed to me that mathematicicans just had much more fun than physicists. This book makes me wonder if I should have given it a second chance, ten years ago.
Anyhow, it is a great book. The author does writes in a very compact way, and there are situations in which rookies like me loose track, but then again, this is entirely compensated by the enthousiasm and wit of the author.
( Dec 30 2005, 10:02:03 PM CET ) PermalinkGrowing a Log
Tonight, I added a couple of more capabilities to the Blammo logging framework. Some of it has been done in order to provide some suppport for Sun's Unified Logging Format. The Unified Logging Format dictates that the message id is prefixing the actual message. Blammo already allowed you to specify the message id explicitly, but I wanted to have Blammo generate it for me, so I added that capability. Additionally, I added a mechanism to copy the JavaDoc comments for a certain event to the message catalog as an explanation.
That means that a message catalog could now potentially look like this:
The message ids have been generated, using the BLAM prefix and starting from message number 200. Both these properties are specified in the relevant section in your Maven pom:
<plugin>
<groupId>com.agilejava.blammo</groupId>
<artifactId>blammo-maven-plugin</artifactId>
<version>0.1-SNAPSHOT</version>
<configuration>
<messageIdPrefix>BLAM</messageIdPrefix>
<messageIdOffset>200</messageIdOffset>
</configuration>
</plugin>
The additional comments for a certain message have been copied from the interface definition of the logger:
/**
* @blammo.logger
*/
public interface EventLogger {
/**
* The application has attempted to divide something by zero, which is
* impossible. This is a bug.
*
* @blammo.level warn
* @blammo.message Attempt to divide {a} by {b}; returning 0 instead.
*/
void logDivisionByZero(int a, int b);
( Dec 20 2005, 11:16:12 PM CET )
Permalink
Agile vs. Monumental
A couple of days ago, I again experienced that traffic jams are just excellent opportunities for contemplation. While thinking about some recent experiences doing architecture work, my mind drifted off and I found myself trying comparing the different definitions of architecture of my customers. (I also found myself in need of the emergency break.)
All of a sudden, it dawned into me that these customers not only had different ideas on the approach for producing the architecture, but also different objectives. I'm sure everybody already figured that out, but quite honest, it was a nano-revelation for me.
I always figured that the objectives of the agile architect were similar to the objectives of the monumental architect, e.g. guarding systemic qualities like performance, scalability, security, etc. But I think I've come to believe that these are really 'afterthoughts' for the agile architect: we will fix it if it becomes a problem.
There is however one thing that can never be an afterthought in an agile project. The focus of an agile architect (aka coach) is predominantly on guarding a quality that is generally not listed as a systemic quality. The agile architect focuses on parallelization of the development process.
If working in parallel is not a requirement, then providing structuring principles is not necessary at all. However, if the size of the team increases beyond two, then there is a need to provide more structure, since people will need to work in parallel.
( Dec 20 2005, 09:30:31 PM CET ) PermalinkBlammo Report
A couple of days ago, I introduced the Blammo way of logging, stating that it would be easier to have a message catalog, for example to be included in your manuals. In reality, I didn't have an example of such a message catalog based on Blammo. Today, I'm happy to announce that I've been able to generate a first message catalog. It is not yet as complete as I want it to be, but I'm getting there.
( Dec 12 2005, 01:37:10 PM CET )
Permalink
Comments [0]
Blammo Revisited
After yesterdays entry, I got two questions about the framework:
- We want to use an ATG logger; how do we do that?
- Is this convenient for debug logging?
Using other low level API's
Normally, if you need something else than the defaults, you are encouraged to inject this other implementation at runtime. You can however also set another default in your code that constructs the initial logger. Here is how you do it, assuming that you are working from the samples givin in my previous entry:
/*
* Using a JDK Logger.
*/
Logger logger = (Logger) BlammoLoggerFactory
.create(Logger.class, new BlammoJdkLog(java.util.logging.Logger.getLogger("Sample2")));
/*
* Or the shorthand:
*/
logger = (Logger) BlammoLoggerFactory.create(Logger.class, new BlammoJdkLogFactory());
/*
* Or do this:
*/
public voidSetBlammoLogFactory(BlammoLogFactory factory) {
logger = (Logger) BlammoLoggerFactory.create(Logger.class, factory);
}
Mixing low-level and Blammo logging
Blammo is most definitely not the ultimate tool for low level debug logging. In fact, you shoul not even consider Blammo for this. That should not be a problem at all, since you can mix and match Blammo with other low level logging mechanisms that you like:
package com.agilejava.blammo.samples;
import java.util.logging.Logger;
import com.agilejava.blammo.BlammoJdkLog;
import com.agilejava.blammo.BlammoLoggerFactory;
public class Sample2 {
private Logger logger = Logger.getLogger("Sample2");
private EventLogger eventLogger = (EventLogger) BlammoLoggerFactory
.create(EventLogger.class, new BlammoJdkLog(logger));
public int div(int a, int b) {
try {
logger.fine("About to do something nasty.");
return a / b;
} catch (ArithmeticException ae) {
if (b == 0) {
eventLogger.logDivisionByZero(a, b);
return 0;
} else {
eventLogger.logUnexpectedDivisionException(a, b, ae);
throw ae;
}
}
}
/**
* @param logger
* The logger to set.
*/
public void setLogger(EventLogger logger) {
this.eventLogger = logger;
}
/**
* @return Returns the logger.
*/
public EventLogger getLogger() {
return eventLogger;
}
/**
* @blammo.logger
*/
public interface EventLogger {
/**
* @blammo.level warning
* @blammo.message Attempt to divide {a} by {b}; returning 0 instead.
*/
void logDivisionByZero(int a, int b);
/**
* @blammo.level error
* @blammo.message Failed to divide {a} by {b}.
*/
void logUnexpectedDivisionException(int a, int b, ArithmeticException ae);
}
}
( Dec 08 2005, 02:54:25 PM CET )
Permalink
Comments [0]
Log, from Blammo!
In my continuing exploration of new ways to make my life easier, there used to be one thing that I couldn't solve in a satisyfing way. I know it sounds silly, but it's logging.
Now I can already hear you go like: "Why on earth would logging be a problem. There are APIs! In fact, there are plenty of them. There is Log4j, the de facto standard. There is JDK Logging, the de jure standard. And there is Commons Logging, if you can't choose between them. In fact, if you count in all of the proprietary logging API's, then - well then you would probably just loose count."
If that's the way you would respond, then I would nevertheless persist that logging can be ugly. There are a number of reasons:
Reasons to Have Another Logging Mechanism
- Configuration: I hate to start a project, and having to configure things first. I know, not all of the logging packages require you to have property files all of the time, but some of them do, and I can't stand it.
- Message Construction: there seems to be no way to do it right. If you use the + operator, then you will be accused of waisting your heap. If you want to be heap-savy, and use
if (log.isDebugEnabled())blocks, then half of your code exists of irrelevant if clauses. If you use the StringBuffer or the MessageFormat class, then you will be accused of obfuscating your code. - Message Catalog: I like having a message catalog of everything that ever could be logged by my applications. If I use Logging API's directly, then it is impossible to construct such a message catalog, since message construction is happening somewhere in my code, and only humans are able to figure that out.
- Resource Bundle: I could use a resource bundle, and a MessageFormat class, but then I will never be sure that the messages defined in the Resource Bundle are expecting particular type number and order of Objects (or Object wrappers of primitives) in order to complete the message. Generally speaking, I hate the fact that I don't have compile time checking of these things. If I remove an Object from the array passed to the MessageFormat class, then I will not be aware of it until a RuntimeException is informing me about it.
- Testing: Testing if certain messages are logged is a disaster. First of all, it is a nightmare to get your hands on the logged messages from your JUnit TestCase. And then, you will need to parse the message to figure out if your message contains the appropriate information. Since the message could be changed in a resource file, your tests may be invalid in no-time. And you were not even interested in the actual message in the first place! You only cared about the specific parts.
Examples
Here are some logging examples. The first example is using JDK 1.4 features:
public int div(int a, int b) {
try {
return a / b;
} catch (ArithmeticException ae) {
if (b == 0) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Attempt to divide " + a + " by " + b
+ "; returning 0 instead.");
}
return 0;
} else {
if (logger.isLoggable(Level.SEVERE)) {
logger.log(Level.SEVERE, "Failed to divide " + a + " by "
+ b + ".");
}
throw ae;
}
}
}
Pretty ugly hu? And it's getting worse if I want to make it a little better; let's use a MessageFormat class instead:
public int div(int a, int b) {
try {
return a / b;
} catch (ArithmeticException ae) {
if (b == 0) {
if (logger.isLoggable(Level.WARNING)) {
String message = MessageFormat
.format(
"Attempt to divide {0} by {1}; returning 0 instead.",
new Object[] { new Integer(a),
new Integer(b) });
logger.warning(message);
}
return 0;
} else {
if (logger.isLoggable(Level.SEVERE)) {
String message = MessageFormat.format(
"Failed to divide {0} by {1}.", new Object[] {
new Integer(a), new Integer(b) });
logger.log(Level.SEVERE, message);
}
throw ae;
}
}
Testing the code above would be extremely complicated. These are just some examples to show why having something else, or something extra would make sense. In Blammo, my code would look like this:
private Logger logger = (Logger) BlammoLoggerFactory.create(Logger.class);
public int div(int a, int b) {
try {
return a / b;
} catch (ArithmeticException ae) {
if (b == 0) {
logger.logDivisionByZero(a, b);
return 0;
} else {
logger.logUnexpectedDivisionException(a, b, ae);
throw ae;
}
}
}
This code is much shorter and cleaner. But then again, in this case, I'm cheating. Instead of using a general purpose logging API, I'm using a Logger that is specific for my kind of events. But hold on, it's getting better: the only thing that I have to do to get this working is not to implement the interface, but simply to define the interface. Blammo will take care of the hard bits.
So the Java example above, actually had some more lines. It defines an inner interface declaration:
/**
* @blammo.logger
*/
public interface Logger {
/**
* @blammo.level warning
* @blammo.message Attempt to divide {a} by {b}; returning 0 instead.
*/
void logDivisionByZero(int a, int b);
/**
* @blammo.level error
* @blammo.message Failed to divide {a} by {b}.
*/
void logUnexpectedDivisionException(int a, int b, ArithmeticException ae);
}
Normally you would need to implement this interface manually, and then make sure that your private Logger reference gets populated with an instance of that implementation. This is where Blammo helps out. Blammo allows you to specify some JavaDoc based annotations, and generates everything for you. There are a couple of things to note here:
Observations
- In Blammo, the message refers to the parameters by name.
- In Blammo, you don't need to pass in Object[] arrays.
- Blammo will check if the parameter references actually resolve to parameters.
- At runtime, Blammo will use the MessageFormat class; the messages in the resource files generated by Blammo will contain '{0}' and '{1}', instead of '{a}' and '{b}'.
- Blammo is able to generate a fairly rich message catalog. The general idea is to use additional ordinary JavaDoc statements to provide details for the event.
- Blammo will use the second part of the operation name as the identifier of the message in the resource bundle. That means '
logDivisionByZero()' will create a property 'DivisionByZero'. This can be overridden by using the '@blammo.idannotation. - Blammo does not have a specific way to write the messages to a particular file or a database, or whatever. Instead, it relies on lower-level logging APIs to take care of that bit. In that sense, Blammo is a little similar to Commons Logging. The main difference is: Commons Logging is providing yet another low-level API on top of existing other low-level APIs. Blammo instead provides a dedicated high-level logging API, on top of existing low-level APIs.
- Blammo works particularly well with dependency injection frameworks. Per default, your classes could use Null Loggers, and have property setters that allow it to be rewired to a real, environment specific Logger.
- Last but not least: Blammo is great (!) for testing. With the low-level API's it would be extremely hard to write a TestCase. With Blammo, it is actually pretty simple:
package com.agilejava.blammo.samples;
import org.easymock.MockControl;
import junit.framework.TestCase;
public class Sample2Test extends TestCase {
MockControl loggerControl;
Sample2.Logger logger;
public void setUp() {
loggerControl = MockControl.createControl(Sample2.Logger.class);
logger = (Sample2.Logger) loggerControl.getMock();
}
public void testDivisionByZero() {
Sample2 sample2 = new Sample2();
sample2.setLogger(logger);
int a = 3;
int b = 0;
logger.logDivisionByZero(a, b);
loggerControl.replay();
sample2.div(a, b);
loggerControl.verify();
}
public void testDefaultDivisionByZero() {
Sample2 sampl2 = new Sample2();
int a = 3;
int b = 0;
sampl2.div(a, b);
}
}
(And for insiders; yes, I do consider this the Stimpy way of logging. Have fun!)
( Dec 07 2005, 09:54:23 PM CET ) Permalink Comments [0]Emacs NXML-Mode Conference 2005
I just returned from the XML 2005 conference in Atlanta, and I had a great time. Not in the least because everybody seemed to be using Emacs as the ultimate XML authoring tool. So I hereby file my suggestion to change the name of the conference to the "Emacs NXML-Mode Conference 2006".
We could also rename the conference to the "PurchaseOrder Conference 2006". I don't think I have seen any presentation not refering to a PurchaseOrder example. Which makes you wonder.... we don't have a dedicated PurschaseOrder spec yet! (WS-PurchaseOrder, XPurchaseOrder, XPO, they all qualify as acceptable XML related spec names. Here's your chance. File your proposals today!
xmlconf2005 ( Nov 21 2005, 10:21:29 PM CET ) Permalink Comments [0]
XML 2005 Day 1
Tutorial day! I attended two tutorials: one about DocBook, and another one about XForms. Norm did the presentation on DocBook; one of the things he explained is why moving to RelaxNG for DocBook v5.* is an improvement. And it really is: as an example, he showed how to remove an element from a content model based on the DTD, followed by an example of the same change in RelaxNG. The DTD version required several pages of customizations. In RelaxNG it only required a couple (4?) lines.
The other tutorial was also interesting. I had not looked at XForms for quite a while, but it's really great to see where XForms is going. It was really amazing to see the presenter pick up an XML document, drop it in an open XForm-based document, and notice the UI wrapping around this piece of XML data.
The real question remains how these things will develop over time. Both XForms and JSF provide a rich declarative validation framework, but it seems awkward that you would have to configure these validation rules for both the XForms based UIs and JSF based UIs; it would be great if these commonalities could somehow be factored into a separate layer upon which both XForms and JSF could rely, but there is no such thing yet.
xmlconf2005 ( Nov 15 2005, 04:00:05 AM CET ) Permalink Comments [0]
Packing my tags
We're a little more than a week away from the XML 2005 conference. This afternoon, I got some time to crawl through the different topics, and it's looking good! After reading a conference schedule, I kind of feel like the robot that you might remember from one of the 80's movies (forgot it's name), that is running around in a library, all excited, shouting "INPUT INPUT" while it's reading a couple of books per minute.
This will be [1] my first visit to an XML only conference, and [2] my first visit to Atlanta. I consider myself to be quite familiar in the mixed Java and XML scene, but this community could be a little different. In any case, I'll make sure to pack a lot of shirts with tags, just to make sure that I blend in. And since this is my first visit to Atlanta: if there is anbody out there who can make some recommendations on places to visit and where to have dinner, then just let me know.
( Nov 03 2005, 05:00:59 PM CET ) Permalink Comments [0]Secretum
Just finished reading "Secretum", the lastest book of Monaldi and Sorti. It's fascinating. It was a while ago since I had read their first book, "Imprimatur" (Amazon), so it took me some time to recall the characters that reappear in this book. The most fascinating thing about the book is that - once you've finished reading the story - it ends with a huge list of references, proving that a lot of the events that have been woven into the story are actually based on historical evidence. (And believe me, that really comes as a surprise.)
I don't think the book has been translated in English yet. It made its first appearance in Holland, since the previous book caused so much disruption in Italy and the Vatican that the authors got problems with their publishers.
( Nov 01 2005, 06:49:23 AM CET ) Permalink Comments [0]On the stability of four feet tables
While I was digging up some information about influenza in Europe (my entire family, including myself have been sick for some days), I ran into this publication. The author prooves that any four-feet table can be put into a stable position by simply rotating it. Don't ask what this has to do with influenza. I find this an amazing discovery; it's just so simple, that I would never have expected that it could be proven mathematically.
You can read more about this in Nature online (http://www.nature.com/news/2005/051024/full/051024-3.html) This is the abstract of the original publication, following by an excerpt of the introduction.
"We prove that a perfect four-feet square table, posed in a continuous irregular ground with a local slope of at most 15 degrees can be put in equilibrium on the ground by a “rotation” of less than 90 degrees. We also discuss the case of non-square tables and make the conjecture that equilibrium can be found if the four feet are on a circle."
"Anybody eating lunch or drinking coffee at the terrasse of the CERN cafeteria has had the following problem. Most of the time the table is not in a stable equilibrium position. It rests on 3 feet and with very little energy it can be made to oscillate so that part of your coffee is spilled at best on the saucer or worse on the table. Why is this? Not because the table is not well built but because the ground is very irregular. Many years ago I thought about this problem, and in a relatively idealized situation I proved that by “rotating” the table (“rotating” is to be explained later) one could find an equilibrium position if the local slope is less than 15 degrees. In practice I did many times the experiment outside the CERN cafeteria, and even though the conditions of the theorem are not really satisfied - the feet are thick, the ground is sometimes discontinuous, but on the other hand, the legs of the tables have some elasticity - I have always succeeded in finding an equilibrium position. I think that my early sketch of a proof dates back from 1995. I presented a tentatively “serious” (but partly incorrect ) proof in 1998 at a seminar at I.H.E.S. in Bures Sur Yvette but it was never written for some serious personal reason."( Oct 30 2005, 12:00:00 AM CEST ) Permalink Comments [0]


