Great CLASSPATH Trick

A lot of Java projects have several JARs you need to put into the CLASSPATH in order to get things to compile properly. Whether you're using jikes or javac, you need to build up the CLASSPATH so that the user's environment isn't expected to provide the correct CLASSPATH for building.

Using gnu make, and assuming that all the JARs are in a single directory - as they usually are, you can do the following:

empty:=
space:= $(empty) $(empty)

JARS:= $(shell find ../libs -name *.jar)
CLASSPATH:= $(subst $(space),:,$(JARS))
list:= find src -name *.java | grep -v /testers/
SRC:= $(shell $(list))
CLASSES:= $(SRC:%.java=%.class)

my.jar: $(SRC)
        javac -classpath $(CLASSPATH) $?
        rm -f my.jar
        jar cf my.jar `find src -name *.class | grep -v /testers/`

This allows you to simply place JARs in the lib directory and they will qutomatically be picked up into the CLASSPATH. Also, this compiles all the java source files that have changed with respect to the jar and then creates a new version of that jar.

UPDATE

I have completely updated the makefile for BKit and here it is:

#
#  This is a very simple makefile for BKit.
#

#	If we're on a platform with jikes, use it as it's faster
ifeq ($(shell uname),Darwin)
JAVAC:=jikes -bootclasspath /System/Library/Frameworks/JavaVM.framework/Classes/
classes.jar:/System/Library/Frameworks/JavaVM.framework/Classes/ui.jar -extdirs
/Library/Java/Home/lib/ext:/Library/Java/Extensions:/System/Library/Java/
Extensions -nowarn
RMIC:=rmic
else
JAVAC:=javac -J-ms32m -J-mx32m
RMIC:=rmic
endif

#	get the CLASSPATH we'll need
CLASSPATH:=/usr/local/MQClientV2:/usr/local/VantagePoint/Jars/vpJava2JFC.jar:
/usr/local/jConnect/4.2/classes:/usr/local/jep/jep.jar

#	get all the Java files that need building
list:= find one -name *.java | grep -v /ado/
SRC:= $(shell $(list))
CLASSES:= $(SRC:%.java=%.class)
#	get all the classes that need rmic-ed
rmics:= find one -name *.java | xargs -J % grep -l UnicastRemoteObject % | 
	sed -e 's/.java//' -e 's:/:.:g'
REMOTE:= $(shell $(rmics))

all: .compile

jar: .compile
	@ rm -f bkit.jar
	@ jar cf bkit.jar `find one -name *.class | grep -v /testers/ | 
	grep -v /ado/`

.compile: $(SRC)
	@ $(JAVAC) -classpath .':'$(CLASSPATH) $?
	@ $(RMIC) -classpath .':'$(CLASSPATH) $(REMOTE)
	@ touch .compile

install-applet: jar
	@ cp bkit.jar $(HOME)/Sites/applets/classes/

clean:
	@ rm -f bkit.jar
	@ rm -f `find one -name *.class`

We get all the rmic classes as well as getting done just what we need. Not bad.