Monday, November 29, 2004

Finally! IDEA has built-in Subversion support

As of Irida build 3117 IntelliJ IDEA finally has built-in Subversion support. I just created a fresh project, looked at the options, looked at version control, and BAM!, there it was. There is nothing now to keep me from using IntelliJ IDEA for all my Java work.

However, you cannot please everyone. Go figure.

Linux VFS tutorial

What a neato article! You build a vitual filesystem in a file with emphasis on ACLs. Time for me to start playing with this more in my shell scripting; it makes an interesting alternative to traditional shar file installers.

Friday, November 26, 2004

Cool IntelliJ IDEA features for ant

I'm not used to using IDEA to run my ant builds, but I'm going to start using this feature as often as possible. I just discovered that when you run an ant target from inside IDEA, and you have the option enabled to Autoscroll to Source, IDEA jumps around in build.xml from target to target as it runs: I can visually trace ant as it executes!

To boot, when it is working on an individual class (compiling, say), it jumps to that source file as it works.

What a great visual indicator of how the build is progressing!

Wednesday, November 24, 2004

Why Java needs delegation

The problem

A problem especially exacerbated in Java by inversion of control (IoC) is composition or delegation v. inheritance. In C++, this is a non-issue given features such as multiple inheritance, private inheritance and using declarations. However, Java has no such help. Just look at this code:

public interface Commuter {
    public void walkToWork();
    public void driveToWork();
    public void flyToWork();
}

And yet another interface:

public interface Parent {
    public void produceChildren();
    public void feedChildren();
    public void disciplineChildren();
    public void teachChildren();
}

And finally a concrete class:

public class Dad
        implements Commuter, Parent {
    private Commuter commuter;
    private Parent parent;

    public Dad(final Commuter commuter, final Parent parent) {
        this.commuter = commuter;
        this.parent = parent;
    }

    public void walkToWork() {
        commuter.walkToWork();
    }

    public void driveToWork() {
        commuter.driveToWork();
    }

    public void flyToWork() {
        commuter.flyToWork();
    }

    public void produceChildren() {
        parent.produceChildren();

Hey, wait! You didn't finish! you cry. You are right; I got bored with all that redundant typing. This is the problem with delegation in Java — the language support sucks and it's all hand-made. What Java needs is proper delegation support.

In C++ it looks like this:

class Dad
  : public HoustonCommuter, public GoodParent
{
};

That's it! (Given suitable implementations of HoustonCommuter and GoodParent.) Even better, just like in Java you can change the implementation:

template<typename A, typename B>
class CommutingParent
  : public A, public B
{
};

typedef CommutingParent<HoustonCommuter, GoodParent> Dad;

If anything, it's now too amazing as you can construct a Dad from the wrong base classes, although latent typing keeps this problem theoretical. (However, note the C++ FAQ on private inheritance as a counter.)

What's to be done?

The solution

The solution is to change Java, of course. :-) I don't suggest C#'s delegate approach, and introducing new keywords is bad policy. What I suggest is both simpler and more expressive, and also more flexible. Let's turn back to the Commuter/Parent example. Try your mind on this:

class Dad implements Commuter, Parent {
    public Dad(final Commuter commuter, final Parent parent) {
        this = commuter;
        this = parent;
    }
}

What's going on here? I'm teaching the Java compiler to take meaning from an otherwise illegal statement: assignment to this. I wave my compiler-writer wand and declare that when a class implements an interface, assignment to this implements that interface with the object assigned (the RHS) provided that the RHS implements the interface.

Internally, I'd teach the compiler for this example to add a hidden Commuter __commuter instance member to Dad, assign to that member, and add the forwarding methods to Dad automatically. I'd expect reflection to work as expected and make all this clear, just as if I'd had coded it all by hand. No magic secrets, please.

More details

If Dad directly implements any of the methods in Commuter or Parent, those let the compiler off the hook and it generates no silent methods. That is:

public class Dad implements Commuter, Parent {
    public Dad(final Commuter commuter, final Parent parent) {
        this = commuter;
        this = parent;
    }

    public void teachChildren() {
        teachSinging();
    }

    private void teachSinging() {
        System.out.println("Mir ist so wunderbar!");
    }
}

This implementation of Dad should provide silent methods for everything except void teachChildren(). Note that this implies you can implement portions of an interface as well:

public interface CommutingParent extends Commuting, Parent {
}

public class Dad implements CommutingParent {
    public Dad(final Commuter commuter) {
        this = commuter;
    }
}

Now Dad will not compile until it implements the methods in Parent. However this leads to an interesting question: what about ambiguities?

public class Dad implements CommutingParent {
    public Dad(final Commuter commuter, final CommutingParent commutingParent) {
        this = commuter;
        this = commutingParent
    }
}

Dad will not compile with the compiler complaining about an ambiguity: which delegate implements Commuter, commuter or commutingParent? The simple approach is best to fix this error:

public class Dad implements CommutingParent {
    public Dad(final Commuter commuter, final CommutingParent commutingParent) {
        this = commuter;
        this = (Parent) commutingParent;
    }
}

Here the (Parent) cast extracts the just the Parent implementation from commutingParent and ignores the Commuter implementation.

A final problem

Back to the earlier example:

public class Dad implements Commuter, Parent {
    public Dad(final Commuter commuter, final Parent parent) {
        this = commuter;
        this = parent;
    }

    public void teachChildren() {
        teachSinging();
    }

    private void teachSinging() {
        System.out.println("Mir ist so wunderbar!");
    }
}

Notice anything funny? Contrast with this:

public class Dad extends HoustonCommuter, GoodParent {
    public void teachChildren() {
        super.teachSinging();
        teachSinging();
    }

    private void teachSinging() {
        System.out.println("Mir ist so wunderbar!");
    }
}

Ok, we call super.teachChildren() before extending the behavior of void teachChildren() so that we add to instead of replace existing behavior. How can I accomplish that now with delegation? Simple, write the exact same code! Since I'm giving meaning to assignment to this, I feel free to extend the meaning of calls through super. The compiler will take this as a request to inline the code for the silent delegation method. It will still not generate the silent method as we need reflection to find the our own code, not the silent method.

The only remaining problem is (ok, so the preceding problem was the penultimate one, not the final one):

public class BeetleDriver implements Driver {
    public void driveToWork() {
        System.out.println("Baby you can drive my car!");
    }
}

And:

public class Dad extends BeetleDriver implements CommutingParent {
    public Dad(final CommutingParent commutingParent) {
        this = commutingParent;
    }
}

Who implements void driveToWork()? It's another ambiguity error and the class will not compile. Back to explicit delegation:

public class Dad extends BeetleDriver implements CommutingParent {
    public Dad(final CommutingParent commutingParent) {
        this = commutingParent;
    }

    public void driveToWork() {
        super.driveToWork();
    }
}

This is just like the solution above for super.teachChildren().

IntelliJ IDEA, Windows, CVS, SSH and SourceForge

I'm having trouble with one of my open source projects, PCGen, getting the fabulous IntelliJ IDEA on Windows XP to integrate with CVS over SSH to SourceForge. When I imported the project into IDEA, it read the connection settings from the CVS/Root which were :ext:binkley@cvs.sourceforge.net:/cvsroot/pcgen. Ok, then. However, IDEA was then unable to make a correct SSH connection and IDEA would simply hang. I had to kill an errant ssh.exe process

I followed the directions on CVSWithSSH except that I really didn't want to add a depedency to PuTTY. PuTTy is great software, but I wanted Cygwin's ssh to do the job if possible.

Then I found SSH and CVS and got an idea. I checked the repository settings for my IDEA project and after some experimenting switched from :ext:binkley@cvs.sourceforge.net:/cvsroot/pcgen to :ssh:binkley@cvs.sourceforge.net:/cvsroot/pcgen. What's the difference?

Using the "ssh" protocol instead of "ext" (external based on the CVS_RSH environment variable), I told IDEA to use its own internall SSH implementation. Amazing! Now everything "just works".

UPDATE: My only complaint now is that IDEA keeps the CVS settings in my user preferences, instead of with the project. Perhaps in the next version. IDEA 5.0 is looking to have quite a nice feature set including serious CSS & HTML support, XML refactoring and the YourKit Java Profiler built right in.

Monday, November 22, 2004

Yet more JNI help

When I posted A litte JNI there were several details I glossed over. One important point: the sample code leaks memory. Why? When you call FindClass, the pointer that the JNI returns needs freeing later on. Rather than deal with such a mundane task directly, I actually wrote a small helper template class and specialized it for jclass:

template<>
struct local<jclass>
{
  JNIEnv* env;
  jclass clazz;

  inline local(JNIEnv* env, const char* name) throw()
    : env(env), clazz(env->FindClass(name))
  { }

  inline ~local() throw()
  { if (clazz) env->DeleteLocalRef(clazz); }

  inline operator jclass() const throw() { return clazz; }

#warning Implement the safe bool idiom
  operator bool() const { return clazz; }
};

There is still one nit: since there is definitely a sense of "validity" for this class (did FindClass find anything?), I should implemnt the Safe Bool Idiom instead of blindly providing operator bool(). But, as they say, I leave that as an exercise for the reader.

Sunday, November 14, 2004

A handy JNI trick for package names

One thing I find myself doing a lot is writing "package/Class" strings in calls to C++ JNI. A shortcut— define them as static members of a struct hierarchy mirroring the Java package hierarchy. To illustrate, take java.lang.Exception. In some header the declaration:

extern struct java
{
  struct lang
  {
    const char* Exception;
  } lang;
} java;

And elsewhere in the matching definition:

const char*
java::lang::Exception = "java/lang/Exception";

(Remember that JNI uses slashes instead of dots to separate package names.)

Now you can write code like this:

inline void
throwJavaException(JNIEnv* env, const std::string& msg)
{
  env->ThrowNew(env->FindClass(java.lang.Exception), msg.c_str());
}

I find using C++ program text that looks like Java program text is easier for me to read and conceptualize. I more interesting problems to occupy my mind than mentally translating strings to class names.

A little JNI

For an integration project at work, I found myself needing to implement portions of a Java class in C++ to access a custom shared library another group wrote. JNI, of course. So I looked around and remembered SWIG for auto-generating things. The problem with SWIG, however, is that it is designed to go C++->Java, and I need to go the other direction.

After some searching, I decided to just go it alone and see what happened. About a half-day later, I had a decent looking setup. First, the GNUmakefile (for some hypothetical project named Pants). Just as important as tests are an easy build (yes, this is for Cygwin):

MAKEFILE = $(word 1,$(MAKEFILE_LIST))

TARGET = Pants

FLAGS = -g3 # -Os -W -Wall

CC = cc
CFLAGS = $(FLAGS)
CPPFLAGS = -I. -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32"
CXX = c++
CXXFLAGS = $(FLAGS) -fabi-version=0 # -Weffc++
JAR = $(JAVA_HOME)/bin/jar
JARFLAGS =
JAVAC = $(JAVA_HOME)/bin/javac
JAVACFLAGS = -g -Xlint:all
JAVAH = $(JAVA_HOME)/bin/javah
JAVAHFLAGS =
LDFLAGS = -L. -L"$(JAVA_HOME)/bin" -L"$(JAVA_HOME)/lib"
TARGET_ARCH = -mno-cygwin # turn off Cygwin-specific dependencies

COMPILE.java = $(JAVAC) $(JAVACFLAGS)
LINK.o = $(CXX) $(LDFLAGS) $(TARGET_ARCH)

%.d: %.cpp $(MAKEFILE)
	@$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; 	  sed 's,\($*\)\.o[ :]*,\1.o $@ : $(MAKEFILE) ,g' < $@.$$$$ > \ $@;
	  rm -f $@.$$$$

%.class: %.java $(MAKEFILE)
	$(COMPILE.java) $<

%.h: %.class
	$(JAVAH) $(JAVAHFLAGS) -jni $(patsubst %.class,%,$^)
	@touch $@ # javah doesn't update the timestamp

SRCS = $(wildcard *.cpp)

all: $(TARGET).jar

-include $(SRCS:.cpp=.d)

# Teach make to generate the header when compiling the source
$(TARGET).o: $(TARGET).h

$(TARGET).dll: $(SRCS:.cpp=.o)
	$(LINK.cpp) -shared -o $@ $^ $(LDLIBS)

$(TARGET).jar: $(TARGET).class $(TARGET).dll
	[ -e $@ ] 	  && $(JAR) uf $@ $^
	  || $(JAR) cf $@ $^

clean:
	$(RM) *~ *.d *.o
	$(RM) $(TARGET).h $(TARGET).class $(TARGET).dll $(TARGET).jar

Ok, then. What is this all for?

You start with a directory listing such as:

  1. GNUmakefile
  2. Pants.cpp
  3. Pants.java

And running make compiles Pants.class, magically creates Pants.h containing the JNI bindings for any native methods in Pants.class, uses Pants.cpp to implement the methods, links Pants.dll, and finally combines Pants.class and Pants.dll into Pants.jar. Easy, peasy. The output is:

Pants.cpp:1:19: Pants.h: No such file or directory
javac -g -Xlint:all Pants.java
javah  -jni Pants
c++ -g3  -fabi-version=0  -I. -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" -mno-cygwin -c -o Pants.o Pants.cpp
c++ -g3  -fabi-version=0  -I. -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" -L. -L"$JAVA_HOME/bin" -L"$JAVA_HOME/lib" -mno-cygwin -shared -o Pants.dll
 Pants.o
[ -e Pants.jar ]   && jar uf Pants.jar Pants.class Pants.dll   || jar cf Pants.jar Pants.class Pants.dll

(The warning in the first line only happens once, and is a side-effect of auto-generating header dependencies. A fix would be very welcome. And the nuisome check for Pants.jar existence is because jar isn't very smart.)

Take a trivial Pants.java:

public class Pants {
    public native void wear();
}

And a simple-minded implementation:

#include "Pants.h"

#include <iostream>

using namespace std;

/*
 * Class:     Pants
 * Method:    wear
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_Pants_wear(JNIEnv* env, jobject self)
{
  cout << "One leg at a time." << endl;
}

Now I find it easier to work with more natural-looking C++ methods than with Java_Pants_wear(JNIEnv*, jobject). Here is my solution. Rather than trying a full-blown peer wrapper (such as JNI++ or Jace), I did the simplest thing that could possibly work. First, a hand-coded matching C++ peer class to the Java class, JPants.h:

// Emacs, this is -*- c++ -*- code.
#ifndef J_PANTS_H_
#define J_PANTS_H_

#include 
#include 

class JPants
{
  JNIEnv* env;
  jobject self;

public:
  JPants(JNIEnv* env, jobject self);
  void wear();
};

#endif // J_PANTS_H_

Then I moved the implementation code from Pants.cpp to JPants.cpp:

#include "JPants.h"

#include <iostream>

using namespace std;

JPants::JPants(JNIEnv* env, jobject self)
  : env(env), self(self)
{
}

void
JPants::wear()
{
  cout << "One leg at a time." << endl;
}

Lastly, I updated Pants.cpp to be a purely forwarding implementation:

#include "Pants.h"
#include "JPants.h"

/*
 * Class:     Pants
 * Method:    wear
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_Pants_wear(JNIEnv* env, jobject self)
{
  JPants(env, self).wear();
}

The only thing left is to have Pants actually do something interesting. If I were to formalize this, I'd write a simple wrapper generator to write the forwarding code and peer class, and provide some helpers such as a std::string factory for jstring. But after a while, I'd be rewriting those other packages I mentioned up front that I was avoiding. It is always so tempting to over-generalize and write meta-code instead of delivering functionality.

UPDATE: There is a definitely gotcha with using Cygwin: the DLL is fine except that Sun's JVM cannot find the symbols in it. The symptom is an java.lang.UnsatisfiedLinkError exception when using the DLL. The reason is esoteric, but the solution is straight-forward. Fix GNUmakefile and replace:

$(TARGET).dll: $(SRCS:.cpp=.o)
	$(LINK.cpp) -shared -o $@ $^ $(LDLIBS)

with:

$(TARGET).dll: $(SRCS:.cpp=.o)
	$(LINK.cpp) -shared -Wl,--add-stdcall-alias -o $@ $^ $(LDLIBS)

UPDATE: I failed to include a very imporant bit of code in Pants.java:

static {
    System.loadLibrary("Pants");
}

Otherwise, the JVM will never find your native methods and you'll see the abysmal java.lang.UnsatisfiedLinkError error. Also I've uploaded a sample ZIP file of the code in this posting along with a simple unit test: http://binkley.fastmail.fm/Pants.zip.

Thursday, November 11, 2004

Custom URLs with Java

One of the cool things about the JDK is that it easily supports custom URLs. Say you had a cool object database that returned result sets as XML documents. You could refer to one with odb://user:pass@server/table_name?field1=blah&field2=borf#row_3 which would fetch the third object as an XML document from the query SELECT * FROM table_name WHERE field1 = 'blah' AND field2 = 'borf'. How would you teach Java to recognize the URL and forward it to your clever implementation code?

First, create a protocol handler:

package protocol.odb;

public class Handler extends URLStreamHandler {
    protected URLConnection openConnection(final URL u)
            throws IOException {
        return new OdbURLConnection(u);
    }
}

(Note the package name: the JDK requries that protocol handlers be in a package named the same as the URL scheme. This is how the JDK maps the URL to your handler.)

Second, create the custom connection:

public class OdbURLConnection extends URLConnection {
    /**
     * Constructs a new OdbURLConnection.
     *
     * @param url the input URL
     *
     * @see Handler#openConnection(URL)
     * @see URLConnection#URLConnection(URL)
     */
    public OdbURLConnection(final URL url) {
        super(url);
    }

    public void connect()
            throws IOException {
        if (connected) return; // noop if already connected

        // Connect to the object database here
    }

    // Override the various getters appropriate to the object database
}

For extra credit, you can make the connection bidirectional. You could then read in an XML POST and update the object database accordingly.

See the excellent RFC 2396 for information on URI syntax (and by extension their subset, URLs).

UPDATE: An even better resource, Chapter 24 by Mike Fletcher from Java Unleashed, 2nd Edition by Michael Morrison, et al entitled Developing Content and Protocol Handlers. Very excellent and blends well with A New Era for Java Protocol Handlers.

UPDATE:See Brian McCallister's excellent help.

Sunday, November 07, 2004

Why chaining constructors is good

Cedric writes why chaining construtors is bad. Actually, what he advocates is concentrating all the construction logic in a single method (e.g., init), and turning constructors into forwarders to this privileged method.

But he does not mention that this is no different from having a single privileged constructor and chaining all other constructors to that. Hence:

class ChooChoo {
    public static final Station DEFAULT_STATION = new Station();
    public static final Conductor DEFAULT_CONDUCTOR = new Conductor();

    private final Station home;
    private final Conductor chief;

    public ChooChoo() {
        this(DEFAULT_STATION, DEFAULT_CONDUCTOR);
    }

    public ChooChoo(final Station home) {
        this(home, DEFAULT_CONDUCTOR);
    }

    public ChooChoo(final Conductor chief) {
        this(DEFAULT_STATION, chief);
    }

    public ChooChoo(final Station home, final Conductor chief) {
        this.home = home;
        this.chief = chief;
    }
}

In my code, init is a privileged constructor (sometimes a private one) which I find more clear. But Cedric mentions that init increases clarity for him. We should pair together. :-)

Saturday, October 30, 2004

Premature design

We just hired a contractor to help out with my project until we can hire someone permanently. I'm having trouble keeping him focused on the coding needs of the present. He wants to look forward, design for the future, and revisit existing design decisions that are well beyond the scope of the project. I admire the breadth of his thinking, but I find the lack of his faith in YAGNI disturbing.

Any suggestions?

Saturday, October 23, 2004

I hate C++

I hate C++, no, really. I've been a C++ fan since I started programming in 1991 and learned about it from a friend, Brian McDonnell, who worked on CLIPS for NASA and was a big OOP fan. It was the first language I learned (in tandem with "C") by mistaking the ARM for a more complete textbook ("annotated") rather than the compiler-writer's guide that it was. And that led to the dragon book as my third computer science text. A rough way to start, but very fun, and Larry Wall is spot on about the value of hubris.

Enough about me.

What happened to the joy of C++? And wasn't the moo book a gas? Clearly I enjoy the stuff. But now I hate C++. The explanation is easy: tools.

After a solid year of Java at its finest, returning to C++ and no good unit test libraries (cppunit being about it), no mock objects, no IDEA or decent Eclipse support, no ant or maven, no good coverage tools, no good code analysis, no good dependency analysis on and on and on. Tools make the programmer. And C++ has dog food for tools compared to the wealth of open-source projects for Java. Now that I'm working on a C++ project, my development efforts are at least doubled for the same work, and I continually feel that I am leaving imporant parts of best practices out of the picture. Nor does it look like that's about to change anytime.

And that is why I hate C++. Goodbye, dear friend.

Sunday, October 17, 2004

Frisson

It was a small fright and not a slight pleasure to see the resuls of scattered conversations with my pairmate Gregor Hohpe make an appearance in such an interesting post. It is satisfying to see prominent ThoughtWorkers like Gregor and Dragos (my first pairmate at ThoughtWorks) getting broader exposure for their interesting ideas. ThoughtWorks is like grad school for good development ideas.

Thursday, October 14, 2004

Installing XP

Having moved on from ThoughtWorks for personal reasons, I find myself in an interesting position. My new employer SimDesk is a mixture of old-style top-down development practice and new-style agile practices struggling to get out. One of my top tasks is helping good triumph over bad in that struggle. What's highest on my task list?

Get CruiseControl running
Without continuous integration builds, it is very hard to track just where the source code base for a project stands. My boss is very excited by this, and now I'm just waiting for an official machine to run on.
Daily stand ups
Daily stand ups keep everyone in the loop, help developers get a larger picture of things and are a great leveler. Not happening yet, but I hope to get some buy in this week.
User story notecards
This is a major point against old-style waterfall. User story notecards are a very visible difference and lead to using development as part of the design process, and to short release cycles. Best news yet: my boss and his boss—who is acting on behalf of the actual customer—were fine with this. I have notecards stuck up on my wall now! And with XP-style estimates.

None of this would have been possible without the environment of ThoughtWorks. The place is like grad-school for best practices; a year there is worth four years at most other places. Now if only they had a Houston office.

UPDATE: I left out mention of the great resource, Extreme Programming Installed by Jeffries et al. And there is a bonus: a group here is alread using an internal Wiki which I immediately latched onto for posting story cards and working out design problems, plus some XP envangelizing. Plus I a co-lead agreed to start daily morning stand up meetings next week. I also find that a small satellite group in Austin is using Scrum, but I don't know that much about it. All in all a good environment to build upon.

Monday, October 11, 2004

CruiseControl and version problems

It took me several days to track down the source of my troubles, but it turns out that the latest versions of CruiseControl, Tomcat and the JDK5 do not play together. To get a working CC build results page, I need these versions with Microsoft:

  • Windows XP SP2
  • CruiseControl 2.1.6
  • Jakarta Tomcat 5.0.27
  • Sun JDK 1.4.2_05

Possibly JDK 1.4.2 works with Tomcat 5.0.28, but I did not try that combination. I spent enough time struggling with it that once I had a working combination, I stuck with it.

Next up: — installing on production which for us is a Linux Mandrake 9 box. No one here is foolish enough to use a Microsoft server for production.

Saturday, October 09, 2004

Templates vs. Generics

Bruce Eckels has yet another brilliant article on Java generics. I've been trying generics out quite a bit and I continue to be disappointed. I would have been much happier if Sun had adopted the more ambitious generics projects wholesale such as Rice's Projet NextGen. Given the state of things, I would jump whole-heartedly into Nice if only it had a decent editor such as IntelliJ IDEA. At last I finally understand first-hand why Microsoft had such a grip on the C++ market with VisualStudio which way back when must have seemed pretty slick to many Windows programmers.

Wednesday, October 06, 2004

Logging into NT with Java

While researching JAAS I scratch-coded this interesting bit:

final String name = "Bob the Builder";
final LoginContext context = new LoginContext(name, null, null, getNTConfiguration(name));

context.login();
context.logout();

Of course, the secret is in getNTConfiguration:

static Configuration getNTConfiguration(final String name) {
    final Map options
            = new HashMap() {
        {
            put("debug", "true");
            put("debugNative", "true");
        }
    };

    final AppConfigurationEntry[] appConfigurationEntry
            = new AppConfigurationEntry[]{
        new AppConfigurationEntry(NT_LOGIN_MODULE_NAME, REQUIRED, options),
    };

    final Map entries
            = new HashMap() {
        {
            put(name, appConfigurationEntry);
        }
    };

    return new Configuration() {
        public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {
            return entries.get(name);
        }

        public void refresh() { }
    };
}

And the super-secret is the value of NT_LOGIN_MODULE_NAME: "com.sun.security.auth.module.NTLoginModule".

The output when I run using all the debug options is:

An attempt was made to reference a token that does not exist.
		[NTLoginModule] succeeded importing info: 
			user name = boxley
			user SID = S-1-5-21-123456789-839522115-1060284298-38670
			user domain = MYDOMAIN
			user domain SID = S-1-5-21-123456789-839522115-1060284298
			user primary group = S-1-5-21-123456789-839522115-1060284298-513
			user group = S-1-1-0
			user group = S-1-5-32-544
			user group = S-1-5-32-545
			user group = S-1-5-4
			user group = S-1-5-11
			user group = S-1-5-5-0-77027
			user group = S-1-2-0
			impersonation token = 7120
		[NTLoginModule] completed logout processing
getting access token
  [getToken] OpenThreadToken error [1008]:   [getToken] got user access token
getting user info
  [getUser] Got TokenUser info
  [getUser] userName: boxley, domainName = MYDOMAIN
  [getUser] userSid: S-1-5-21-123456789-839522115-1060284298-38670
  [getUser] domainSid: S-1-5-21-123456789-839522115-1060284298
getting primary group
  [getPrimaryGroup] Got TokenPrimaryGroup info
  [getPrimaryGroup] primaryGroup: S-1-5-21-123456789-839522115-1060284298-513
getting supplementary groups
  [getGroups] Got TokenGroups info
  [getGroups] group 0: S-1-5-21-123456789-839522115-1060284298-513
  [getGroups] group 1: S-1-1-0
  [getGroups] group 2: S-1-5-32-544
  [getGroups] group 3: S-1-5-32-545
  [getGroups] group 4: S-1-5-4
  [getGroups] group 5: S-1-5-11
  [getGroups] group 6: S-1-5-5-0-77027
  [getGroups] group 7: S-1-2-0
getting impersonation token
  [getImpersonationToken] token = 7120

Friday, October 01, 2004

Upside-down inheritance

Here is a classic, persisted object in Java:

public class Foo extends Persisted {
    // fields

    // constructors

    // getters, setters
}

Pretty dull. What's wrong with that?

Now here's a typical query-by-example (QBE) method in some finder class (assuming something suitable like Hibernate or iBatis, and a supporting framework):

public Foo findFooByExample(Foo foo) {
    return (Foo) findByExample(FOO_TABLE, foo);
}

And here's a typical data transfer object (DTO) for passing around the found Foo to some other layer of the program:

public class FooData {
    // same fields as Foo

    // same constructors as Foo

    // same getters, setters as Foo
}

And then there's methods which take a Foo and need testing:

public void doBar(Foo foo) {
    // Does Bar look at anything in Persisted, or just Foo?
    // The test code needs to mock the persisted methods, if so.  Rats.
}

Oh, wait. Hrm. Lots of code duplication, lots of overhead to make changes, extra things to test. This is not looking so good. Why is that?

The inheritance is upside-down!

Once you disabuse yourself of the preconception that domain/database objects (DO) extend a persistence base class, the solution is trivial:

public class Foo {
    // fields

    // constructors

    // getters, setters
}

public class FooPersisted extends Foo implements Persisted {
    // fields, getters, setters for persistence
}

Now the QBE example uses Foo for input, and FooPersisted for output; FooData goes away completely; and the doBar method explictly requires either a Foo or a FooPersisted, making it clear if it does or does not fiddle with persistence.

And a bonus: it is almost always less work to implement the two or three fields and getter/setters which persistence uses rather than the larger number of fields which the DO uses. And as they are the same few fields everywhere, you can automate the process using code generation or annotations.

(Aside: Or course, it would be even easier still if Java only supported mixins. Then you just defined FooPersisted as:

public class FooPersisted extends Foo, Persisted {
    // empty -- no further code needed
}

No new keywords; no confusion—super always refers to the first class mentioned in the extends list.

But that is a different post.)

Safer collections

In my post on IndexMap I mentioned in passing SafeHashMap. What is that?

The JDK is very useful but has some warts. One of the worst is this inconsistency: if you try to index into a list with a non-existent index (i.e., beyond the end of the list) the collections throw IndexOutOfBoundsException. But what happens when you try to fetch from a map with a non-existent key? The JDK map implementations silent insert a null value into the map for you and return it. This leads to the following anti-idiom:

Value getValue(Map map, Key key) {
    return (Value) map.get(key);
}

See the problem? Now all code dealing with map anywhere in the program needs to test for null values and decide how to handle them, or else be happy with NullPointerException:

for (Iterator it = map.values().iterator(); it.hasNext(); ) {
    Value value = (Value) it.next();

    if (null == value)
        handleNullValue();
    else
        doTheRealWorkWhichIsTheWholePoint(value);
}

Try coding that 10 times real fast.

What is the solution? Force the correct idiom in the first code fragment:

Value getValue(Map map, Key key) {
    if (!map.containsKey(key))
        map.put(key, createMissingValue(key));

    return (Value) map.get(key);
}

And to enforce this idiom, extend a concrete class such as HashMap with a safe wrapper, hence SafeHashMap, and forbid missing keys or null inserts:

public Object get(Object key) {
    if (null == key) throw new NullPointerException();
    if (!containsKey(key)) throw new IllegalArgumentException();

    return super.get(key);
}

public Object put(Object key, Object value) {
    if (null == key) throw new NullPointerException();
    if (null == value) throw new NullPointerException();

    return super.put(key, value);
}

Friday, September 24, 2004

IndexMap

In my project there are several idiomatic uses of JDK collections. One is using Map to uniquely index domain objects by some field. The code is simple:

public class IndexMap extends SafeHashMap {
    public static interface Mapper {
        public Object getKeyFor(final Object value);
    }

    private final Mapper mapper;

    public IndexMap(final Class keyClass, final Class valueClass,
            final Mapper mapper) {
        super(keyClass, valueClass);

        this.mapper = mapper;
    }

    public IndexMap(final Class keyClass, final Class valueClass,
            final Mapper mapper, final Collection values) {
        this(keyClass, valueClass, mapper);

        addAll(values);
    }

    public void add(final Object value) {
        put(mapper.getKeyFor(value), value);
    }

    public void addAll(final Collection values) {
        for (final Iterator it = values.iterator(); it.hasNext();)
            add(it.next());
    }
}

(SafeHashMap is another JDK collection extension. It forbids null keys and values, and requires they be of certain classes.)

Idiomatic use looks like:

new IndexMap(KeyType.class, DomainType.class, new IndexMap.Mapper() {
    public Object getKeyFor(final Object value) {
        return ((DomainType) value).getKey();
    }
}, initialValues);

Which indexes a collection of DomainType domain objects by the key property.

UPDATE: Because of editing several files at once, I suffered a brain fart and mixed IndexMap (the point of this post) with AutoHashMap (another, still interesting collection).

Tuesday, September 21, 2004

Two ways to model tables in code

Generally I run into two ways to model tables in code.

The first way is to have a single object type respresenting a full row in a table, matching the SQL query SELECT * FROM TABLE. I'm going to call this way the model-the-table method. Every use of the table in code gets all fields regardless of need. This is wasteful but simpler to maintain.

The second way is to have several object types, each representing a single use of a row in the table, matching the SQL query SELECT COLUMN_1, COLUMN_2 FROM TABLE. I'm going to call this way the model-the-use method. Each use of the table in code gets only the fields needed. This is more precise but harder to maintain.

I'm undecided which I like better and have used both in projects, even within the same project. Perhaps enlightenment will come my way.

My pairmate, Karthik Chandrasekariah pointed out to me the similarity of this choice to using the Adapter pattern. Only instead of changing the view of an underlying code object with an adapter, you change the view of a database table.

Domain objects and compareTo

I wrote earlier about domain objects and boolean equals(Object) and how to handle primary keys. What about int compareTo(Object)? The same remarks about primary keys still apply, and the code pattern is:

public class Something implements Comparable {
    /* ... */

    public int compareTo(final Object o) {
        final Something that = (Something) o;
        int compareTo = firstPK.compareTo(that.firstPK);
        if (0 != compareTo) return compareTo;
        compareTo = secondPK.compareTo(that.secondPK);
        if (0 != compareTo) return compareTo;
        // ... likewise for other primary keys
        return lastPK.compareTo(that.lastPK);
    }
}

This sort of comparison method will group sorts by the order of comparison, so that firstPK groups together, then secondPK, etc.. If, say, you sorted [Apple, Blue], [Orange, Orange], [Apple, Red], this way, they would be grouped as [Apple, Blue], [Apple, Red], [Orange, Orange].

Layers and containers

I've been thinking about how J2EE containers work. They provide a world of many layers: application-container, container-Java libraries, Java libraries-byte code, byte code-JVM, JVM-platform libraries, platform libraries-native code, native code-OS, OS-hardware. (And there are, of course, calls from higher layers to lower layers even further down.) That's a lot of layers. I wonder what could be stripped out?

For example, Java handles thread scheduling for Java code, but the OS does the same for native code. How much are Java threads mapped onto native threads? (The answer varies quite a bit between platform and JVM implementation.) The same question arises comparing byte code to native CPU instructions. How much of a JVM could be performed directly by an OS?

There is plenty of research in these areas already (I was going to make a list of interesting links, but Google turned up so much, it hardly seems worth the effort—Google sure changes how research works), so I am looking forward to reading more about these ideas over time. Layers are good for abstraction, but over time the most successful abstractions become concrete and implementors take advantage to improve performance and transparancy. Witness pointers: C abstracted hardware addressing as pointers, which then C++ abstracted as virtual methods, which then Java abstracted as methods: success begats success.

I expect the same trend to continue as byte code slowly displaces native code and JVM-like things appear more in hardware and operating systems such as the cool work at Transmeta.