(back to ProgrammingTips)
Java is a popular programming language written by Sun Microsystems. It's an object-oriented language that runs inside a "virtual machine" which, at least in theory, allows code to run on many different machines. Sun calls this "Write once, run anywhere", and in practice it actually works reasonably well, although it took years for this to happen.
Java is extremely popular in commercial software development - it's dominant in the area that I work in: operations support software for communications companies. It's not at all popular in the Free Software community because it's a proprietary product owned and controlled by Sun.
The Java home page is
http://java.sun.com/; you can download a developer kit or run-time from there. Java per se is a proprietary product, but there are many free projects that aim to provide all (or part) of the Java environment as Free Software.
http://www.dwheeler.com/java-imp.html lists many of those projects.
See also:
JavaProgrammingBookmarks,
JbossTips
Books
Bruce Eckels
Thinking in Java
Nutshell
Development Tools
building:
ant - "like make only without make's wrinkles"
modelling:
argouml - a UML modelling tool that can generate Java skeletons.
debugging: jswat
database access: isql, squirrelsql
Profiling
There are many expensive commercial tools for profiling Java programs while they're running, but since Java has the JVMPI interface pretty much anyone can hook into the JVM at run time and find out what's going on. This is another category of programs where there seem to be far too many half-baked efforts, but here are my notes from a few hours of fooling around with various tools.
Mike's Profiler -
http://mjp.sourceforge.net/ looks promising, has actual documentation and the maintainer seems to be maintaining it on an ongoing basis. The GUI is easy to understand. Unfortunately it seems to run very slowly and crash before JBoss can fully boot up.
NOTE - I need to test 0.06 which has a statistical sampling mode
JTreeProfiler -
http://sourceforge.net/projects/jcoverage/ this one streams to an XML file on a per method invocation basis so it's probably unsuitable for anything but trivial profiling (booting JBoss wrote a 2.3GB file). The analysis GUI is interesting and very graphical but hard to make sense of.
JPerfAnal -
http://sourceforge.net/projects/jperfanal/ can you think of a more unfortunate name for a performance analysis tool? In any case this guy seems to have the right idea in that he reads the stock Sun profiler output so he doesn't need a platform-specific library to gather data. Unfortunately his GUI is lame and there's not one word of documentation.
Extensible Java Profiler -
http://ejp.sourceforge.net/
JMP -
http://www.khelekore.org/jmp/ GTK GUI, written in C.
JRat -
http://jrat.sourceforge.net/ takes an interesting approach - you "instrument" your code after you build.
Infrastructure
tomcat - servlet engine, jboss - j2ee container, openejb - ejb container, avalon - server framework, maverick - presentation framework
Libraries
trace logging: log4j
Coding Conventions
Use Sun's
http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html and override what you feel is wrong. Personally, I feel that the 80 column constraint is too limiting; I prefer to allow people to use 132 column line widths.
When something is an identifier, and you feel that you must append "Id" in some form to the name, use
ID not
Id. It's easier to type and reflects that most people call it an "eye-dee" not an "id".
When a class has a member variable that holds multiple items, don't make a
setFoo(Collection foos)
method, make an
addFoo(Foo foo)
method instead. Maintain the collection (or set or whatever) internally. The difference is that there's some type checking in the second approach whereas the first approach lets the client pass a
Collection
full of
anything in. It's also often more convenient for the client to call
add()
a few times rather than create their collection, fill it, and then
set()
it. If they want to look at it you can return either a collection/set/list (some interface) or you can return an array or iterator of some sort.
Misc
Here's a cute hack to enable token substitution in java property files:
http://www.sys-con.com/java/source.cfm?id=1228
Using Java on Debian GNU/Linux
When I tried to run Sun's JDK 1.3.1 on Debian Sid (in March 2002) I got the following error:
/home/tcabot/local/Linux/jdk/bin/i386/native_threads/java: error while loading shared libraries: libstdc++-libc6.1-1.so.2: cannot open shared object file: No such file or directory
. This can be solved by linking to the existing libstdc++, i.e.
ln -s /usr/lib/libstdc++-libc6.2-2.so.3 /usr/lib/libstdc++-libc6.1-1.so.2
.
Java is a proprietary language (controlled by Sun) but there are a few Free implementations of the compiler, JVM, and class libraries. If you're running a new version of Debian you can apt-get
gcj
and
kaffe
.
$ gcj -C HelloWorldApp.java
$ kaffe -addclasspath . HelloWorldApp
Java is very resource-intensive: cpu, memory, and processes. So you might bump into the limits that Unix uses to limit individual user resource consumption. An important one is
max user processes
which you can see if you run
ulimit -a
. You probably want to bump this up to 1020 or so:
ulimit -u 1020
. Other limits that you might bump into are
SHMMAX
and
SHMANY
which you can set using files in
/proc/sys/kernel/
or by setting values in
/etc/sysctl.conf
.
Arrays vs Collections
Why don't people use arrays in Java? It seems to me that people get so excited about
Collection
,
Set
,
List
etc that they forget about arrays. Arrays have some definite issues, but they also have some advantages. Arrays are fixed-length so they're not good if you're not sure how many things that you're going to put into them in advance. Their big advantage (which limits their use) is that they're strongly typed. This can be a big advantage in many cases, i.e. where you've got a bunch of the same thing. In this case an array is nice because it enforces type safety in a way that a
Collection
doesn't.
In summary, an array is the correct data structure to use where you have a known number of objects all of the same type.
Float sucks
Binary arithmetic (e.g. Java float) doesn't cut it when applied to money - it's not accurate on the right side of the decimal point. Java seems to have the answer in java.math.BigDecimal but from what I've seen on the web it's not a very good implementation.
IBM has proposed a replacement of the BigDecimal class, the website is at
http://www2.hursley.ibm.com/decimalj/. The site does a great job of explaining why decimal arithmetic is better than binary and also has many interesting links. They also have an implementation available but it's under a very restrictive license, you can only use it for 90 days and then you must destroy it - there's no way to buy it, either.
The IBM page points to a commercial implementation of a BigDecimal class at
http://users.belgacombusiness.net/arci/math/. It's not very expensive - 500 Euro (which is closer to $500 than those common-market pinkos would hope!). It claims to be fast and have good formatting features.
There was another implementation but it seems to have fallen off the net. Google had cached entries for a package called TCE/Java at
http://www.voicenet.com/~hsk0/tce/ but it seems to have fallen off the net. The guy that wrote it is Howard Kapustein, maybe he'll show up again.
Misc Notes
IBM's JVM 1.4.1 for GNU/Linux doesn't seem to recognize old-style timezone names. My
/etc/localtime
was a link to
/usr/share/zoneinfo/US/Eastern
and the JVM would never use daylight savings - it was always GMT+5. When I changed the link to
/usr/share/zoneinfo/America/New_York
it worked fine. See
http://www.mainframeforum.com/t590240.html which seems to be relevant despite being a mainframe forum.
public class date { public static void main(String[] argv) throws java.io.IOException {System.out.println(new java.util.Date()); }}
--
TobyCabot - 28 Dec 2001 - 10 Nov 2003