... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2009-06-22

Infinitest

Infinitest is an Eclipse plug-in that runs JUnit tests incrementally and continuously as you edit the classes under test.

It is a fantastic idea -- if it worked.  Unfortunately, it is not quite working yet.  Infinitest would find failures in my sandbox projects, but none in our main code base.  Maybe it cannot follow plug-in references yet?  The Eclipse error log always reports "No tests found to run for change []".

2009-06-18

Shrinking SQL Server Log Files

In SQL Server, the transaction log files grow unboundedly until you take some action.  To completely discard old transactions, perform the following steps in the database in question:

backup log databaseName to disk='nul:'
dbcc shrinkfile('logical log file name', 64)

If you actually want to save the contents of the transaction log, use a better pathname than nul.  If you do not know the logical log file name, execute this query:

select * from sys.database_files

In practice, I have found that you may have to run the BACKUP LOG command a few times to get the file to shrink down significantly.

2009-06-16

SQL Server 2005 vs Table-valued Functions

Experimentation has revealed that SQL Server 2005 will sometimes come up with a better query plan if you express joins using IN clauses than if you express the same joins explicitly.  For example:

SELECT
  ...
FROM dbo.fnProduction(...) AS prod
INNER JOIN dbo.tmpProjectFilter AS filter
  ON filter.projectId = prod.projectId
  AND ...

expresses a join between a normal table and a non-procedural table-valued function (i.e. pure query).  It runs quite slowly.  But if you re-express the query thus:

WITH
  filter AS (
    SELECT
      projectId
    FROM dbo.tmpProjectFilter
    WHERE ...
  )
SELECT
  ...
FROM dbo.fnProduction(...) AS prod
WHERE prod.projectId IN (SELECT * FROM filter)

... it runs faster.  It would seem that the latter form is doing a better job than the former when injecting the relevant query conditions into the table function.

This is a tool to consider when "optimizing" "declarative" SQL.

Actors... Dynamic Typing Redux?

I was reading the chapter in Programming In Scala that introduces actors.  It noted that it is a good idea to use named types for messages as opposed to basic types like tuples, arrays and lists.  This makes it easier to locate an actor who could possibly process the message.  Sound advice.  However, I was struck by the fact that if you expose Actors as part of an API, that part becomes effectively untyped (or "duck typed" in popular parlance).

I was struck further by the fact that almost all of the Erlang code to which I have been exposed uses tuples with wild abandon.  Of course, Erlang is mostly untyped so that should be no surprise.  Scala, at least, offers machinery to prevent dynamically typed signatures from escaping a module boundary (for example, by making sure an implementation has-a actor instead of is-a actor).

As a final bit of irony, I observe that Smalltalk's message selector syntax offers a pretty decent solution for identifying objects that can handle (synchronous) messages -- provided you choose a name more distinctive than at: or at:put:.  The irony lies in the fact that Smalltalk is frequently held up as the prototype for duck-typing.  I wonder if Smalltalk's message selector syntax arose to solve the very problem of searching for methods?

2009-06-13

Say "No" To Identifiers

A colleague of mine was recently faced with a large refactoring task that included changing the names of lots of program elements. When he was done, he swore that he would never name anything again.

When thinking about that statement, I wondered just how far you could get without using any identifiers in a Java program. As you might imagine, I didn't get that far. However, the result was still amusing (for me, at least). What follows is a fairly obscure implementation of "Hello, world". Be warned that this source code crashes the CheckStyle plug-in in Eclipse...

import static java.lang.Class.*;
import static java.util.Arrays.*;

public class _ {

    public static void main(String[] __) throws Exception {
        ________ _ = new ________();
        _._().__().__().__().__().__().__()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._().___()._().__().__().__().__().__().__()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._().___()._().__().__().__().__().__().__()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._().___()._().__().__().__().__().__().__()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._().___()._().__().__().__().__().__()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._().___()._().__().__()
                .__().__().__().__()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._().___()._().__().__().__().__().__().__()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._().___()._().__().__().__().__().__().__()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._().___()._()
                .__().__().__().__().__().__()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._().___()._().__().__().__().__().__()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._().___()._().__().__().__().__()
                .__().__()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._().___()._().__().__().__().__().__()
                .__()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._().___()._()
                .__().__().__().__().__().__()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._().___()._()
                .__().__().__().__().__().__()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._().___()
                ._().__().__().__().__().__().__()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                .___()._().__().__().__().__().__().__()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._().___()._____()._().__()
                .__().__().__().__().__()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._().___()._().__().__().__().__()
                .__().__()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._().___()._().__().__()
                .__().__().__().__()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._().___().______()
                ._().__().__().__().__().__().__()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._().___()._().__().__().__().__().__().__()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._().___()._().__().__().__().__().__().__()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._().___()
                ._().__().__().__().__().__().__()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._().___()._().__().__().__().__().__()
                .__()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._().___()._().__().__().__().__().__()._()._()._()._()
                ._()._()._()._()._()._()._()._().___()._().__().__().__().__()
                .__().___()._().__().__().__().__().__().__()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._().___()._().__().__().__().__().__()
                .__()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._().___()._().__().__().__().__().__().__()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._().___()._().__().__().__().__().__().__()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._().___()._().__()
                .__().__().__().__().__()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._().___().____()
                ._().__().__().__().__().__().__()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._().___()._().__()
                .__().__().__().__().__()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._().___()._().__()
                .__().__().__().__().__()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._().___()._().__().__().__().__().__().__()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._().___()._()
                .__().__().__().__().__().__()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._().___()
                ._().__().__().__().__().__().__()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._().___()._().__().__().__().__().__()
                .__()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._()._()._()._()._()._()._()._()._()._()._()._()._()._()
                ._()._().___()._______()
        ;
    }
}

class ________ {
    Object _;
    Object[] __ = {};
    Object[] ___ = {};
    char ____;
    char[] _____ = {};
    char[] ______ = {};
    ________ _______ = this;
    int ________ = 1;
    
    ________ _() {
        ____ += ________;
        return _______;
    }
    
    ________ __() {
        ____ <<= ________;
        return _______;
    }

    ________ ___() {
        _____ = copyOf(_____, _____.length+________);
        _____[_____.length-________] = ____;
        ____ = 0;
        return _______;
    }
    
    ________ ____() {
        __ = copyOf(__, __.length+1);
        __[__.length-________] = _________();
        return _______;
    }
    
    ________ _____() throws Exception {
        _ = forName(_________());
        return _______;
    }
    
    ________ ______() throws Exception {
        _ = ((Class<?>)_).getField(_________()).get(null);
        return _______;
    }

    ________ _______() throws Exception {
        _ = _.getClass().getMethod(_________(), String.class).invoke(_, __);
        return _______;
    }
    
    String _________() {
        String __________ = new String(_____);
        _____ = ______;
        return __________;
    }
}

2009-06-10

Compiler Bug in Eclipse 3.4

Eclipse 3.4 generates bad bytecode for the following Java:

package a;

abstract class AA {
    final String _value = "the value";

    protected String get() {
        return _value;
    }
}

public abstract class A extends AA {
}


package b;

public class B extends a.A {

    public static void main(String[] args) {
        B b = new B();
        b.doit();
    }

    private void doit() {
        new Runnable() {
            public void run() {
                System.out.println(get()); // IllegalAccessError thrown here
            }
        }.run();
    }

}

An IllegalAccessError is thrown on the indicated line.  A comparison of the bytecode generated by Eclipse versus that from Javac reveals only one significant difference, in the synthetic accessor method generated in B that is necessary to give B$1 (the Runnable) access to the protected method get():

   Javac:   invokevirtual #1;  //Method get:()Ljava/lang/String;

   Eclipse: invokevirtual #33; //Method a/AA.get:()Ljava/lang/String;

The Javac-version is invoking the method by its unqualified name.  The Eclipse version is using a qualified name.  Apparently the JVM gets grumpy with the latter.

This is reported as fixed in Eclipse 3.5 -- see Eclipse's Bugzilla, bug #249107.

Blog Archive