In the company I’m currently working for we are using the Team Foundation Server as a version control system. No for developers of C# or any other Microsoft related programming language this is probably fine. However being a Java developer TFS is less then perfect. In fact it is a near nightmare.
We are using various IDE’s for editing our Java projects, meanly because different developers like different IDE’s. Personally I’m using Netbeans, which has perfect Subversion, Git, CVS and Perforce support. Some other developers use IntelliJ from Netbrains. Which is sorta expensive and the version we are using has no support for TFS at all.
So when I want to edit a simple file I first locate it in my IDE, which takes me about 5 seconds. Then I need to look up its location on disk, followed by opening the completely useless Team Exporer. Then I again need to look up the file in TE, followed by a check-out. The whole process to the point that the file is checked out and ready to go takes probably about 1 minute, each and every time.
On an average day I probably waste up to an hour checking out files, and commiting them back into the version control system.
To ease the burden a bit I’ve tried the SvnBridge tool to link my IDE’s Subversion system with TFS, but this tool has many flaws. Just a few of which are:
So for now I’m stuck. Really, really, really stuck.
Ever since Java 1.4 the usage of the enum type is supported. For those who don’t know an enum is a more elegant way to store constant options. Below is a simple example of how it enhances your code:
public static final int ANIMAL_DOG = 1; public static final int ANIMAL_FISH = 2; public static final int ANIMAL_CAT = 3;
Into something a bit more object oriented:
public enum Animal {
Dog,
Fish,
Cat
}
But when you have the need to serialize the enum values then you may have to use a bit complicator code. It is supported just not out of the box. So lets say I want to predefine the ordinal number and add a name for each animal in my enum. Then I would have to add something similar to this:
public enum Animal {
Dog(10, 'Swoop doggie'),
Fish(20, 'Blub'),
Cat(30, 'Garfunkel');
int iOrdinal;
String iName;
private Animal(int aOrdinal, String aName) {
iOrdinal = aOrdinal;
iName = aName;
}
}
Now each one of the enums values consists out of a name and a custom ordinal which can be used to save the value in a database or represent it in a form. Off course you would have to add methods to obtain the name and ordinal like:
public String getName() { return iName; }
public int getOrdinal() { return iOrdinal; }
That introduces a second problem, if you represent the enum Animal by its ordinal on for example a webpage you will need to be able to regenerate the correct enum value by its ordinal representation. To do this you could add a method to lookup the correct Animal for any ordinal like:
public static Animal getAnimal(int aOrdinal) {
for(Animal lAnimal : values()) {
if (lAnimal.getOrdinal() == aOrdinal) {
return lAnimal;
}
}
return Animal.Dog; // default value required
}
Recently I started working with MS Access databases, I know not the best choice. I ran into a really weird problem with the database, which I didn’t expect.
I have a relativly simple select query which contains a distinct. Something like “select distinct id, content from table”. Nothing fancy so you’d expect the content of the table excluding all duplicates.
But this is also where the weirdness begins with MS Access. I was using this type of query to select data for my search engine. But some data wasn’t included for some reason.
After a lot of debugging my queries and code it turned out that MS Access ODBC was only returning the first 255 characters of a MEMO field. So I thought the driver was to blame, until I ran the same query in MS Access itself. As it turns out Access was the one truncating MEMO fields to VARCHAR(255) fields when using a DISTINCT in a query.
As a Java webdeveloper you are faced with a lot of different aspects of development. One is testing and debugging code, to do this you need an application server like Tomcat. One of the issues I recently encountered was the need to control various Tomcat instances with a single Ant build script. Below are some of the solutions I’ve used to manipulate Tomcat.
Note: some parts of this script rely on the ant-contrib library. Download this library and include it in the tomcat.xml with the following code:
<taskdef resource="net/sf/antcontrib/antcontrib.properties"> <classpath> <pathelement location="./ant-contrib-1.0b3.jar"/> </classpath> </taskdef>
Though starting tomcat may seem easy. You could just use the development IDE (like Netbeans) to start and stop Tomcat, but what this lacks is the ability to control several instances with easy shortcuts. So I defined the following Ant macrodef in a file called tomcat.xml:
<macrodef name="tomcat-start">
<sequential>
<trycatch>
<try>
<if>
<not><http url="http://localhost"/></not>
<then>
<java classname="org.apache.catalina.startup.Bootstrap"
fork="yes"
dir="${tomcat.dir}"
spawn="true"
jvm="${tomcat.java.home}/bin/java">
<jvmarg value="-Dcatalina.home=${tomcat.dir}"/>
<jvmarg value="-Dcatalina.base=${tomcat.dir}"/>
<jvmarg value="-Djava.io.tmpdir=${tomcat.dir}/temp"/>
<jvmarg value="-Djava.endorsed.dirs=${tomcat.dir}/common/endorsed"/>
<jvmarg value="-Xdebug"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"/>
<classpath>
<pathelement location="${tomcat.java.home}/lib/tools.jar"/>
<pathelement location="${tomcat.dir}/bin/bootstrap.jar"/>
</classpath>
<arg line="start" />
</java>
<waitfor maxwait="10" maxwaitunit="second" checkevery="5000">
<http url="http://localhost"/>
</waitfor>
<echo message="Tomcat started"/>
</then>
<else>
<echo message="Tomcat already started..." />
</else>
</if>
</try>
<catch>
<echo message="Unable to start tomcat"/>
</catch>
</trycatch>
</sequential>
</macrodef>
This macro is really easy. First it starts of by checking if tomcat is not already running (well actually it just checks to see if there is something running on port 80). If nothing is running then tomcat is started using the java defined by the ant property tomcat.java.home. This macro also depends on some other properties that are set by a different macro, which will be a bit further on in the post. Tomcat is started by using the Bootloader class provided by the server, to make sure it loads correctly the classpath is set.
The last step in the macro is to wait for tomcat to start, this has to be done since we start tomcat in a seperate java instance (the spawn option).
Off course you also want to be able to stop tomcat to load some new data, or an entire web-app. I use the following macro to stop Tomcat:
<macrodef name="tomcat-stop">
<sequential>
<trycatch>
<try>
<java classname="org.apache.catalina.startup.Bootstrap"
fork="yes"
dir="${tomcat.dir}"
spawn="true"
jvm="${java.home}/bin/java">
<jvmarg value="-Dcatalina.home=${tomcat.dir}"/>
<jvmarg value="-Dcatalina.base=${tomcat.dir}"/>
<jvmarg value="-Djava.io.tmpdir=${tomcat.dir}/temp"/>
<classpath>
<pathelement location="${tomcat.java.home}/lib/tools.jar"/>
<pathelement location="${tomcat.dir}/bin/bootstrap.jar"/>
</classpath>
<arg line="stop" />
</java>
<kill-java name="Bootstrap" />
<echo message="Tomcat stopped" />
</try>
<catch>
<echo message="Unable to stop tomcat forcing shutdown....."/>
<kill-java name="Bootstrap" />
</catch>
</trycatch>
</sequential>
</macrodef>
Just like with the starting of Tomcat I use the provided Bootloader class to instruct tomcat to stop. Again I use the java that is set in tomcat.java.home as well as some other properties loaded by another macro. Since Tomcat sometimes fails to stop gracefully (due to poorly designed webapps) you also have to kill the Java process of Tomcat. This is done with the call to kill-java.
As you saw in the tomcat-stop macro I used a macro called kill-java to make sure that Tomcat is really killed and no longer running in the background. The macro is as follows:
<macrodef name="kill-java"
description="Forcefully stop tomcat....">
<attribute name="name"/>
<sequential>
<!-- Execute the jps and check for any Java process with the provided @{name} attribute -->
<exec executable="${tomcat.java.home}/bin/jps" output="pid.out.file" />
<!-- Load in the name / pid file and strip all information except the PID -->
<loadfile srcfile="pid.out.file" property="pid.out">
<filterchain>
<linecontains>
<contains value="@{name}"/>
</linecontains>
<tokenfilter>
<deletecharacters chars="@{name}"/>
<trim/>
<ignoreblank/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadfile>
<echo message="Killing java process with pid ${pid.out}"/>
<!-- Kill the process, warning this only Works on Windows -->
<exec spawn="true" executable="taskkill">
<arg line="/PID ${pid.out}" />
<arg line="/F" />
</exec>
<delete file="pid.out.file" />
</sequential>
</macrodef>
This macro is really simple and relies on the jps application provided by Java. This application returns a list of all running processes with name and process id (PID). All we need to do is get the line containing the process name provided and strip everything except the PID.
Please note: the task killing the proces is designed for Windows, you could change this with kill in Linux.
Though you now have all you need to manipulate tomcat there is one last macro that we are tegenkant upon. That is the initializer of the various Tomcat properties. I use the following macro:
<macrodef name="tomcat-init">
<attribute name="from"/>
<sequential>
<property name="tomcat.dir" value="${tomcat.@{from}.dir}"/>
<property name="tomcat.server" value="${tomcat.@{from}.server}"/>
<property name="tomcat.port" value="${tomcat.@{from}.port}" />
<property name="j2ee.server.type" value="${tomcat.server}" />
<taskdef name="webapp-stop"
classname="org.apache.catalina.ant.StopTask"
classpath="${tomcat.dir}/server/lib/catalina-ant.jar"/>
<taskdef name="webapp-start"
classname="org.apache.catalina.ant.StartTask"
classpath="${tomcat.dir}/server/lib/catalina-ant.jar"/>
</sequential>
</macrodef>
This little macro will initialize tomcat for a specific environment (for exemple DEV). Of course none of this works without the loading of some preset properties in a property file tomcat.properties. Which contains the following data:
tomcat.java.home=C:/jdk1.5.0_22_32b tomcat.DEV.dir=d:/jakarta/tomcat5.0 tomcat.DEV.server=tomcat55-DEV tomcat.DEV.port=8000 tomcat.MAIN.dir=d:/jakarta/tomcat5.0-MAIN tomcat.MAIN.server=tomcat55-MAIN tomcat.MAIN.port=8000
To load the property file just include the following instruction in the build script:
<property file="./tomcat.properties" />
A short while back I wrote a quick review on the beta of Netbeans 6.5 and that it had some issues. Since the final version was released some time ago I thought it was time for a new review. This time of the final version.
The reason for me not to write one straight away was simple, I first wanna play around a little to find all the pleasant features and those less pleasant ones.
The first thing you expect is this new version to be bigger, better and the best one yet. Well it is bigger in size, with 190MiB for just Java development. So this means a lot more time downloading, but hey that’s a one time thing.
So lets move onto something more relevant. Is it better then Netbeans 6.1. Lets summorize some of the issues I had with the previous version and see if the problem is solved:
So are there any other changes that would make you consider moving from Netbeans 5.5 to 6.5?
Well have there been any changes that would make you wanna switch to the new version.
Unfortunattely not all is good in the world of Netbeans. There are also some new bugs, some of which are really annoying.
As a final note: is it worth upgrading to this version. Then I’d have to say hell yeah, it’s a lot better then previous versions. If you are a PHP developer however I suggest not using it, for the moment. Especially when you are already using Zend-Studio, which is still a lot better.