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. :-)