Archive for February, 2005

New EJB3 draft available

I am happy to announce that the
EJB3 Early Draft 2 is
now available from Sun’s Web site.  As usual, please send your comments to
the EJB3 feedback alias.

Collection.toArray() quiz

Martin spotted a

few inconsistencies in the new Generic Collections
and wonders why…

But a couple of aspects of the new generics-enabled collections framework
annoy me. For example, the Collections interface is declared as
Collection<E> and the
add method, for example, is
correctly declared as:
    boolean add(E object)
So I cannot help but wonder why, then, is
remove declared as:
    boolean remove(Object object)

and

Similarly, the toArray() method should be declared as follows:
    E[] toArray()
Instead of:
    Object[] toArray()

Rest assured, this is not an oversight, these methods were designed this way
for two very good reasons.

Can you see why?

Here are hints if you get stumped (in white):

  1. Existing 1.4 code would break with this definition.
  2. Try to implement this method for all Collections.

 

BattleStar Galactica 2003

I just finished watching the first season of
BattleStar Galactica 2003 and all
I can say is…  wow.

I wasn’t very impressed with the four-hour pilot that aired on SciFi last year,
but I decided I was intrigued enough to try and watch the show when it could
come out.  The problem is…  it never did.  For some reason, Sky
started showing it in September last year and it took a few more months for it
to appear on SciFi, where it is airing as we speak.

The screenwriters of BattleStar Galactica 2003 have taken a lot of liberties with the
original characters and storyline, but if you can live with that, the show has some tremendous assets
and it will keep you wanting for more week after week.

Don’t be fooled by the first episodes and hang on.  The new Galactica is very
stylishly slow and is casting a lot of parallel plotlines that seem to be
unrelated or even hard to follow.  It only gets better week after week,
until the thirteenth episode where you will find some answers at the price of
one of the best cliffhangers I have seen in a long time.

I can’t wait for season two.

Gosling on unsafe code


In a
recent talk about .Net, James Gosling made the following comment:

Microsoft

Elevating the spam alert level

As some of you may have noticed, I have now installed
CAPTCHA protection for comments on my
weblog.  It was made necessary by the most recent of onslaught link spam
that I just received.  MT-BlackList has worked really well for me ever
since I installed it and until yesterday, the
previous massive spam
attack
I received happened a month ago.

For some reason, MT-BlackList didn’t stop yesterday’s attack, which resulted
in one hundred (yes, exactly one hundred) link spam comments to be posted across
thirty blog entries.

What’s comforting is that despite the sophistication of spammers, they still
tend to always include some common pattern in their spam entries (IP, email
address, top-level domain, etc…)  which makes it easy for me to
obliterate their entire deed of evil in less than a minute.  Still, this
creates a certain amount of stress on my servers and, as a matter of principle,
I want to make their life as hard as possible.

So I installed a package called
SCode, which is a
CAPTCHA plug-in for Movable Type.  It’s quite simple and uses a Perl
library to display numbers in a picture.  There are much more complicated
solutions (involving not only digits but letters of various fonts warped by
random transforms while still identifiable by humans), but for now, I’d like to
see if this simple system will be sufficient to foil comment link spam on my
blog.

The installation was pretty easy but it still required me to edit Movable
Type’s source code directly, which is certainly a very unfriendly way to provide
a plug-in.  I don’t know if it’s due to the its implementation or Perl, but
the concept of plug-in in Movable Type is laughably primitive.  We are
definitely spoiled in Java land.

 

Testing asynchronous code

A user recently submitted his problem on the TestNG mailing-list:  he needed to send asynchronous messages (this part hardly ever failed) and then wanted to use TestNG to make sure that the response to these messages was well received.

As I was considering adding asynchronous support to TestNG, it occurred to me that it was actually very easy to achieve:

private boolean m_success = false;

@BeforeClass
public void sendMessage() {
  // send the message, specify the callback
}

private void callback() {
  // if we receive the correct result, m_success = true
}

@Test(timeOut = 10000)
public void waitForAnswer() {
  while (! m_success) {
    Thread.sleep(1000);
  }
}

In this test, the message is sent as part of the initialization of the test with @BeforeClass, guaranteeing that this code will be executed before the test methods are invoked.

After this, TestNG will invoke the waitForAnswer() test method which will be doing some partially busy wait (this is just for clarity: messaging systems typically give you better ways to wait for the reception of a message).  The loop will exit as soon as the callback has received the right message, but in order not to block TestNG forever, we specify a time-out in the @Test annotation.

This code can be adapted to more sophisticated needs:

  • If the sending of the message can also fail and you want to test that as well, you should turn the sendMessage() into a @Test method as well, and in order to guarantee that it will be called before waitForAnswer(), simply have waitForAnswer() depend on sendMessage():
    @Test(groups = { "send" })
    public void sendMessage() {
      // send the message, specify the callback
    }
    
    @Test(timeOut = 10000, dependsOnGroups = { "send" })
    public void waitForAnswer() {
      while (! m_success) {
        Thread.sleep(1000);
      }
    }
    

    The difference with the code above is that now that sendMessage() is a @Test method, it will be included in the final report.

  • It is not uncommon for messaging systems to be unreliable (or more precisely, "as reliable as the underlying medium"), so your business logic should take into account the potential loss of packets.  To achieve this, you can use the "partial failure" feature of TestNG:
    @Test(timeOut = 10000, invocationCount = 1000, successPercentage = 98)
    public void waitForAnswer() {
      while (! m_success) {
        Thread.sleep(1000);
      }
    }
    

    which instructs TestNG to invoke this method a thousand times, but to consider the overall test passed even if only 98% of them succeed (of course, in order for this test to work, you should invoke sendMessage() a thousand times as well).

“Partial failures” are a new feature of TestNG 2.1, which will be released very soon.