Thursday, October 25, 2007

Unit Testing (1): Overview

First article of a series: Use unit testing with open source Java components, in the environment of Swing UIs, J2EE server components, database access (esp. hibernate), web applications, etc. Unit testing is an important part of Test Driven Development (TDD). Admittedly, I have mostliy ignored this topic up to now. Obviously, the overview I have over my own code was enough to detect, place and correct bugs; working with others' code, detecing errors was usually easy, leaving them to fix it ;-) Also, I was always of the opinion that "my" projects were not applicable for Unit Testing ... complicated UIs, enterprise architectures, complex databases, J2EE deployment, etc. Luckily, others have worked on developing frameworks for most of these purposes.

Test-Driven Development

First write the tests, then the structure of the class to implemented, then run the tests. They'll fail, as there is no implementation yet. So, do the coding, test it regularly, until the tests don't fail any longer ... finshed, sort of.

JUnit

JUnit is the most-used Java testing framework. There are so many good tutorials out there, so I don't see the need to write another one. Read one or more of
  • http://www.junit.org/
  • http://junit.sourceforge.net/
  • http://www.ibm.com/developerworks/library/j-ant/
  • http://www.torsten-horn.de/techdocs/java-junit.htm
In the following, I will use JUnit 4.4. Version 4 changed a lot of the usage of Test Cases and such, using Java 5 annotations.
  • http://www.frankwestphal.de/JUnit4.0.html
  • http://www.mm.informatik.tu-darmstadt.de/courses/helpdesk/junit4.html
  • http://radio.javaranch.com/lasse/2006/07/27/1154024535662.html
  • http://www.instrumentalservices.com/content/view/45/52/
I will also make use of the assertThat statement which was introduced with JUnit 4.4, because it makes much of the test code more readable, especially the error messages.
  • http://junit.sourceforge.net/doc/ReleaseNotes4.4.html

Sample

We write a simple utility for concatenating the textual representation of list elements, with a user-defined concatenation string. Having the list ("Hello", "world", "!"), CollectionUtils.collectionToString(list, ", ") should produce "Hello, World, !".

Unit Test for collectionToString

We start with the unit test.
public class  CollectionUtilsTest {
@Test public void testCollectionToString() {
 final List <String> list1 = Arrays.asList("Hello", "World", "!");
 final String comma = ", ";
 final String result1 = CollectionUtils.collectionToString(list1, comma);
 // we can check the complete string
 assertEquals("Hello, World, !", result1);
 // or the items
 for (String s: list1)
   assertThat(result1, containsString(s));
 // and, all items except that last, need to be followed by ", "
 Iterator  it = list1.iterator();
 while (it.hasNext()) {
   String s = it.next();
   if (it.hasNext())
     assertThat(result1, containsString(s+comma));
 }
}
}
assertEquals() is quite easy to understand, imported via import static org.junit.Assert.assertEquals, and compares its two parameters for equality. Usually, a first parameter should be added that contains the message to print, if the two values are not equal.

Code for collectionToString()

Of course, we also need the CollectionUtils class.
public class CollectionUtils {
// for the moment, we don't do anything
public static String collectionToString(List<?> list, String comma) {
 return null;
}
That's enough to run a unit test ... with eclipse, you just need to start either the test case class (CollectionUtilsTest above) with "Run as JUnit Test", or -- alternatively -- the whole project, which runs all unit tests in the selected package.

First test run

java.lang.AssertionError: expected:<Hello, World, !> but was:<null<
...
  at sbr.jut.demo.CollectionUtilsTest.testCollectionToString(CollectionUtilsTest.java:29)
...

Coding collectionToString

public static String collectionToString(Collection coll, String comma) {
StringBuilder sb = new StringBuilder();
String sComma = "";
for (String s: coll) {
  sb.append(sComma);
  sb.append(s);
  sComma = comma;
}
return sb.toString();
}
And, now, the unit test runs through ... until we start some demonic testing ;-)

Special test cases

Of course, null pointers and stuff need to be taken care of, especially ...
assertEquals("collectionToString(null, null)", "",
CollectionUtils.collectionToString(null, null));
assertEquals("collectionToString(null, null)", "",
CollectionUtils.collectionToString(Collections.EMPTY_LIST, null));
final String result2 = CollectionUtils.collectionToString(list1, "");
assertEquals("HelloWorld!", result2);
final String result3 = CollectionUtils.collectionToString(list1, null);
assertEquals("HelloWorld!", result3);
Nice, we start with the first NullPointerException
java.lang.NullPointerException
  at sbr.jut.demo.CollectionUtils.collectionToString(CollectionUtils.java:18)
  at sbr.jut.demo.CollectionUtilsTest.testCollectionToString(CollectionUtilsTest.java:45)
...
, start fixing our implementation, until we end with ... no NPE!
public static String collectionToString(Collection coll, String comma) {
if (coll==null)
  return "";
if (comma==null)
  comma = "";
StringBuilder sb = new StringBuilder();
...
}
So, that is enough for the beginning ...

Sunday, October 21, 2007

Java programming dynamics

A very good series of articles about Java reflection (how to access a class' members and methods by name), class loading, and bytecode manipulation can be found at the IBM pages (April '03 - June '04):

If you want to learn something about the one the reasons that make Java such a powerful languate, read it. These features are, e.g., used by JEE servers or persistence frameworks to automatically determine the methods and fields to be deployed, for accessing the Java 5 @Attributes (not in the articles, yet comparably easy), and to code or derive proxy classes for the deployed services. Part 1:
  • .class file format
Part 2:
  • Hierarchy of class loaders
  • fields and methods by reflection
  • security of reflection, and how to disable it (e.g., to access private members(1))
  • reflection performance
Part 3:
  • Using reflection for processing command line arguments
Part 4:
  • Inject bytecode into existing methods with javaassist
  • introduce method timing into compiled code
  • Java Aspect Oriented Programming (AOP)
Part 5:
  • Intercepting class loading
  • modifying class bytecode on load
  • introduce method timing into code at load time
Part 6:
  • Code conversion
  • class mutilation made easy
Part 7:
  • The Byte Code Engineering Library (BCEL) (also have a look at ASM, also, as this library tries to correct BCEL's deficits)
  • using "coding constructs" instead of "bytecode assembler"
  • the verifier of BCEL
  • disassembling with BCEL and its graphical display
Part 8:
  • Reflection on performance
  • building a glue class
  • improved performance of code generation vs. reflection
Notes: (1) I know you shouldn't do this, especially not with human men ...

Tuesday, October 16, 2007

Auto-Repeat of Server Calls

Problem: When doing client/server-programming, the client calls a function on the server -- EJB, RMI, Web-Services, etc., in a language such as Java. Sometimes, the connection to the server gets lost, as the server is restarted, redeployed, network was down and up again, etc. Then, the client's call to the server fails; after reconnecting, it should be possible to repeat the call and get the wanted result. Possibly, the reconnection will take some time, if the network has a longer "outing". How can we ensure that the call is done in any case, even if there are transient network/deployment problems? Solution 1: The client's Business Delegate (you have one, haven't you?) calls a "ping()" or another such method before calling the real business method on the server. If the connection is broken, catch the exception, try to reconnect, until such a ping goes through. Disadvantages:

  • doubles the number of c/s calls
  • if the ping succeeds, but the real call fails due to problems in this nano second, you're out of luck
Solution 2: Wrap the call to the server inside a runnable, and repeat the call until it succeeds. Requires a language like Java, that supports runnable concepts. Let's see ... some code, untested, out of thin air.
 protected IServer mServer;

public ResultObject businessMethod(final int intParam, final String stringParam)
    throws BusinessException {
 class BusinessMethodRunnable implements Runnable() {
   private ResultObject result;
   public void run() {
     // do the server call itself, and store the result.
     result = mServer.businessMethod(intParam, stringParam);
   }
   public ResultObject getResultObject() {
     return resultObject;
   }
 }

 BusinessMethodRunnable runnable = new BusinessMethodRunnable();
 // wraps the call, to ensure successful completion
 callMethod(runnable);
 return runnable.getResultObject();
}

protected void callMethod(Runnable runnable)
   throws BusinessException {
 // repeat, until the loop is left with return after a successful call
 while (true) {
   try {
     if (mServer==null)
       // should block until the connection has been established
       connectToServer();
     // do the real call here.
     runnable.run();
     return;
   }
   // a business exception needs to be passed to the calling code
   catch (BusinessException e) {
     throw e;
   }
   // a runtime exception also needs to be passed to the calling code ...
   catch (RuntimeExceptione ) {
     throw e;
     // alternatively:
     // throw new BusinessException("RuntimeException caught", e);
   }
   catch (Exception e) {
     logException(e);
     // connection down, no resources to be freed(?)
     mServer = null;
   }
 }
}

Restoring Word 95 files on Windows 95 after crash

Some of us are still using Windows 95. (Probably none of "us", as I doubt any of those systems is able to surf the net ;-) Mostly on machines that need it ... as nothing newer runs. And, of course, for these systems, there is only Word 95 and companions. Also, these machines still have floppy drives. Not to forget -- most of the users of these systems are a bit digitally ... challenged. Now, there is a user who thought saving files on a floppy disk would save them ... in case of a system/harddisk crash. Not as a backup, but for working on the file. Well. As saving on a floppy takes some time, it's usually not done that often. And computers crash. So, we have an hours old file on a floppy, a rebooted system, and an old version of office that may or may not have auto-recovery files. And if it has those, where are they stored, if not in the working directory? Which is a floppy. 3/4 of an hour telephoning later, the file was found in c:\windows as "Sicherungskopie von ...". Rename it to .doc, and open it ... there it is. Wait ... first, we need to explain, still via telephone, how to make windows show the extension ... otherwise, you can't change its extension. Well, I should just send the bill for nearly an hours work ... probably the same as a new old computer for the user ;-)

Tuesday, October 09, 2007

Avr32 Studio and .d files

Has been some time since I wrote this, so it's high time for publishing it ...!
There seems to be a problem with the Atmel AVR32 studio. It is based on eclipse, to develop C/C++ software for the embedded AVR32 chips.
The following error message is (often) given, when a project is recompiled:
make -k all
src/main.d:1: *** multiple target patterns. Stop.
Build complete for project aixC-BoxFirmware
This usually happens when the previous build was not successful, b/c one ore more files could not be compiled.
The reason seems to be the following line in the automatically generated Debug/src/*.d files:
src/main.d src/main.o: ../src/main.cpp ...
It seems, make is not really able to cope with the multiple main.d main.o: statement ...?
The .d files are responsible for checking all file dependencies, i.e., which files need to be recompiled if one header has been changed.
After a clean, which deletes *.d, a full build works.
avr32-linux-gcc is called with the parameters
-MMD -MP -MF"src/main.d" -MT"src/main.d"
which means:
Generated src/main.d (-MF) with the target src/main.d (-MT), for all user include files, and compile the source (-MMD), and generate phony targets for depended files (-MP).
So, theoretically, only
src/main.d: ...
should appear in the src/main.d file ...
Workarounds:
1. Delete all .d files before recompiling
not nice ... looses all dependency information
2. Fix the generated .d files
The following, a bit obscure sed command can be run inside Project/Debug to fix the .d files.
find . -name '*.d'|xargs sed -ie 's#\.d src/[^/]\+/[^ /\.]\+\.o:#.d:#g'
// do I need .d or .o?
The real problem seems to be s.th. else ... the makefile itself (src/subdir.mk) has a rule for building src/main.o from src/main.cpp, and the .d file contains another rule ... strange version of make ...?
The real problem is the inclusion of C:/home/Projekte/Avr32/aix-AVR32-libs/libserial-0.5.2/src/
which gives the other ":" that raises the error ...
1. use a relative path
2. use make 3.80 ...
This error is usually encountered in other situations:
1. a file name contains spaces (windows makes, mostly)
2. a file name contains : (windows again ;-)
http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_16.html
http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_4.html#SEC40
Have fun,
Sebastian
See also
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=315323
You've run into one of our known issues:
Bug #5452
Referencing external folders in managed make projects when using GNU make 3.81 causes build failures. This is caused by GNU make no longer supporting Windows-style path names. GNU make 3.80 works as expected.
The known issues are described in the release notes, which are available on atmel.com. They are also included in the AVR32 Studio Help.
Note that the release notes were not available on the website until quite recently, and the links in the Welcome page appear to be buggy, so I'm not blaming you for not reading them. This will be addressed for the 1.0 release.
Run the cygwin setup.exe and try to downgrade Make to 3.80, that should help.

Saturday, September 01, 2007

Exporting hi-resolution images from OpenOffice.org Draw

I can't use OpenOffice.org at work, so I try to use it for private stuff, as far as possible. Sometimes, though, I start wondering why ... In the my current version of OpenOffice Draw (2.0.4, updated to 2.2.1, still the same ), it is impossible to export an image in a different resolution than 96dpi. Unless one uses workarounds like eps+ghostscript, pdf, or a macro. I loaded an foto from my camera, 2272x1704 (4 MP), added some numbers and lines, and exported it into jpg, png etc. ... and got 1016x762. With different jpeg compression qualities, of course, but no different sizes. Joe pointed me to the OO QA tracker, issue 4499; a short summary:

  • the problem is known since May 2002
  • it was closed due to a misunderstanding of the problem in July 2002
  • reopened shortly after (OO 1.0)
  • since then, reasons for not fixing it have been given ... main problem: all filters need to be extended with the same functionality, thus, an extension to all the export dialogs needs to be requested, designed and implemented
  • last post, "No promises but I try to do something for 2.3 here"
(I just wonder why the export dialog is part of the filter, and not of the common export handling code.) Thanks to bryancole and jbarwick, there is one workaround: Take the following macro code, add it to OpenOffice, and run it ... It exports the current page (with white borders) or the current selection into a given .jpg file, with manual setting of resolution and quality. Maybe someone has a lot of time on his/her hands and wants to write a dialog that does the same? Sub ExportCurrentPageOrSelection REM Filter dependent filter properties Dim aFilterData (7) As New com.sun.star.beans.PropertyValue Dim sFileUrl As String ' set the width and height you want aFilterData(0).Name = "PixelWidth" aFilterData(0).Value = 1704 aFilterData(1).Name = "PixelHeight" aFilterData(1).Value = 2272 ' no real idea what the logical width/height does ... and what units it is in? ' original was 140 and 98.89 ... aFilterData(2).Name ="LogicalWidth" aFilterData(2).Value = 1704 aFilterData(3).Name ="LogicalHeight" aFilterData(3).Value = 2272 ' jpeg quality aFilterData(4).Name ="Quality" aFilterData(4).Value = 85 aFilterData(5).Name = "ColorMode" aFilterData(5).Value = 0 aFilterData(6).Name = "ExportMode" aFilterData(6).Value = 1 ' resolution, for use when loading in another image application aFilterData(7).Name = "Resolution" aFilterData(7).Value = 600 ' the place to put it ... file:///C:/temp/image.jpg should work for Windooze sFileUrl = "file:///home/meself/export-1.jpg" REM A smart person would force this to be a Draw or Impress document xDoc = ThisComponent xView = xDoc.currentController xSelection = xView.selection If isEmpty( xSelection ) Then xObj = xView.currentPage Else xObj = xSelection End If Export( xObj, sFileUrl, aFilterData() ) End Sub Sub Export( xObject, sFileUrl As String, aFilterData ) Dim xExporter xExporter = createUnoService( "com.sun.star.drawing.GraphicExportFilter" ) xExporter.SetSourceDocument( xObject ) Dim aArgs (2) As New com.sun.star.beans.PropertyValue Dim aURL As New com.sun.star.util.URL aURL.complete = sFileUrl aArgs(0).Name = "MediaType" aArgs(0).Value = "image/jpeg" aArgs(1).Name = "URL" aArgs(1).Value = aURL aArgs(2).Name = "FilterData" aArgs(2).Value = aFilterData xExporter.filter( aArgs() ) End Sub Note: OpenOffice.org 2.3.0 is out now (Sept 17th, 2007), yet this problem is unchanged.

Thursday, August 30, 2007

C++ String-Utils

Ever had the problem of wanting to use (s)printf to format a string into an STL/StdC++ std::string instance? The only thing STL says is, "use strstream", which I don't agree with ... (s)printf is easier to use once you get used to the %s stuff, and often cleaner to read. Thus, I wrote my own method ... maybe I just used to much String.format() in Java ;-)

StringUtils.hh

#ifndef STRINGUTILS_HH_
#define STRINGUTILS_HH_

#include <string>


std::string formatString(const char* format, ...); 

#endif /*STRINGUTILS_HH_*/

StringUtils.cc

#include "StringUtils.hh"
#include "BufferUtils.hh"

#include <stdarg.h>
using std::string;

/**
 No need to be afraid about memory leaks, segfaults 
   or buffer overflows (hopefully)
 - the 2kB buffer is freed on return (destructor)
 - the std::string is instantiated before the 
   buffer is freed, and returned on the stack
 - vsnprintf checks the buffer length, and the last char 
   is ensured to be a '\0'
*/
std::string formatString(const char* format, ...) {
 Buffer buffer(2048);
 va_list vl;
 va_start(vl, format);
 vsnprintf(buffer, buffer.bufferSize(), format, vl);
 buffer[buffer.bufferSize()-1] =0;
 return string(buffer);
}

C++ Buffer-Utils

A common C++ problem: allocate some memory block, use it inside a function, and make sure the memory block is freed when exiting the function, even if an early return statement, an exception (or a segfault) or s.th. happens. Best way: Create a class, allocate the memory block in the constructor and free it automatically in the destructor. Instantiate the class locally (i.e., on the stack), problem solved. Some conversion operators to get the mem block as char*, void* etc needed ... Additionally, a small method to nullify a pointer after free'ing the allocated memory with free(). Of course, when using C++, the clean way would be to use new char[] and delete[] ... yet I don't like these ones when I work with an unspecified memory block.

BufferUtils.hh

#ifndef BUFFERUTILS_HH_
#define BUFFERUTILS_HH_

#include <cstdlib>

void freeAndNull(void* &pBuffer);

class Buffer {
private:
 int miBufferSize;
 void* mpBuffer;
 
public:
 Buffer(int bufferSize) 
  : miBufferSize(bufferSize), mpBuffer(malloc(bufferSize)) { 
  // empty
 };
 
 ~Buffer() {
  freeAndNull(mpBuffer);
 }
 
 int bufferSize() { 
  return miBufferSize;
 }
 
 operator char*() {
  return (char*)mpBuffer;
 }

 operator void*() {
  return mpBuffer;
 }
};

#endif /*BUFFERUTILS_HH_*/

BufferUtils.cc

#include "BufferUtils.hh"

void freeAndNull(void* &pBuffer) {
 if (pBuffer)
  free(pBuffer);
 pBuffer = NULL;
}

GPG and IDEA

There are several posts and publications out there on the net about why not to use IDEA with gpg, and how to install the idea.dll plugin if you do it anyway. Yet we did not finde any information about what to do if a certain private/public key pair wants to use IDEA only, possibly, because it was created with pgp2 compatibility. Yet there are some easy steps to change the preferred ciphers of a key, and thus to avoid IDEA when using the key for encryption (especially encrypting to self and thus for all gpg mails that the person sends).

gpg --edit-key 0x12345678
pub  1024D/######## created: 2007-02-03  expires: never     usage: SC
                     trust: unknown      validity: unknown
sub  2048g/########  created: 2007-02-03 expires: never     usage: E
[ unknown] (1). user <mail>

Command> showpref
[ unknown] (1). user <mail>
     Cipher: [1], CAST5, AES256, AES192, AES, 3DES, TWOFISH
     Digest: SHA1
     Compression: ZIP, Uncompressed
     Features: MDC, Keyserver no-modify
the [1] stands for IDEA as the (first) preferred cipher, though it is not a known one in the current gpg installation ... otherwise, IDEA should stand there. So, just set the prefs ... unfortunately, all of them have to be set in one command as a string ...
Command> setpref AES256 AES192 AES CAST5 3DES SHA1 SHA256 RIPEMD160 ZLIB
BZIP2 ZIP Uncompressed MDC
You can do this only with your own key, of course, and need to enter your passphrase (1). Test it, and publish the key anew to the usual key servers. As the preferences are set per user id, and one key may contain a bunch of them, you might have to set the prefs for all user ids seperately ... I didn't try yet. if anything breaks, use setpref w/o any parameters to reset to default values.
Command> setpref
Maybe this helps you as well, if no one else can decrypt the mails you wrote with thunderbird, enigmail and gpgp ... (1) If you are running on windows and use German Umlauts or other diacritical characters, don't be surprised if your passphrase is not accepted in a shell, while enigmail or some other GUI accepts it ... windows cmd.exe has a different character set/code page than the windows system usually uses!

Graphical user interfaces for GPG

BTW, some nice gpg software for windows (linux/unix has gpa, anyway).

A stone age NVidia card and a modern TFT

After some years, I decided to replace my 17'' CRT with a modern 19/20'' TFT. First, had some looks on the internet for good choices, and some in a computer store. Left me with about 4 different Samsung models to choose from. Luckily, I went to the computer store of my confidence ... The guy asked me about my graphics card, s.th. I had not thought about. GeForce 2 MX 200/ELSA Gladiac 311 (32MB, AGP, several years old). "Oh, I'd recommend one of the 16:10 widescreen ones for what you do, yet, your graphics card won't do it ... 1280x1024, the default modes from that time, up to 2048x1536, but no 1400x1050 nor 1680x1050 ... Maybe you should just get a new computer ;-)" Well, I had a check at home ... officially, neither mode is supported (1400x1050 aka SXGA+, 1680x1050 aka WSXGA+), some sites say at least SXGA+ is supported (mainly ebay sellers ...), manuals are not really available as ELSA busted twice since. So I just decided to try it out.

Setting resolution in Xorg

Linux, opensuse 10.2, yast2, sax2: Just set 1400x1050 and it worked. My eyes started running, was hard to read anything, yet it worked. Had to adjust the size and position, of course. Set 1680x1050 and it seemed to work ... yet the Xorg log told me it was using 1600x1024 or s.th. instead. One can't have everything.

Rotating the screen

Next question ... if I get a pivotable TFT, can I do this in Linux? No problem ... Alexander Koenig "told" me
Section "ServerFlags"
...
  Option "RandR" "on"
EndSection

Section "Device"
....
  Option "RandRRotation" "on"
  Option "RenderAccel" "On"
EndSection
and
xrandr -o [left|normal|right]
It just worked.

Setting resolution in windows

Every few weeks or months, I need to boot into my windows system ... there are just a few things which don't really work on wine or vmware player. Found a nice tool EnTech Taiwan PowerStrip that should be able to set manual timings ... didn't need it, though, as the NVidia detonator control centre(1) already has an item "manual timings". Set it to 1400x1050, and got a virtual screen of 1400x1050, and a physical of ... no idea, a bit less. Tried again with 84Hz instead of 85Hz ... and it just works. Seems nvidia tries to use one of the existing modes if the image(?) frequency is already known ... Did the same with 60Hz, and with 1600x1050 ... same results, 84, 80, 60 Hz no problem, 85Hz - virtual screen as wanted, physical smaller. Seems I can buy the Samsung 203B (2) after all ;-) (1) center ;-) (2) Sorry, German page

Thursday, August 16, 2007

C++ typesafe casting

Often, C++ classes are just casted to what is needed by

Subclass* sc = (Subclass)p;
This can lead to unexpected program behaviour, as no error is thrown in the case the p is not an instance of Subclass*; only a bit later, the programm will surely crash. Thus, the clean way is
Subclass* sc = dynamic_cast<SubClass*>(p);
of course, this requires run time type information; they should be available, if libstdc++ is available, too. This can also be used to determine the runtime type of a (class) pointer:
if (dynamic_cast<SubClass*>(p)) { ... }
Unfortunately, the C++ standard does not(?) provide any method to find out about class hierarchies ...

Call-by-reference in Java; StringBuilder

Objects are always passed by reference to Java functions. Thus, any change to the objects are reflected after function return. Of course, changes to the object referencs (the variables themselves) are lost on return. This does not apply to primitives (int, boolean, float). Also, several classes, String, Integer, Double, Boolean, are immutables; thus, it is impossible to change them after construction. Thus, they cannot be used for call-by-reference (demonstration). StringBuffer, on the other hand, can nicely demonstrate this:

static void changeStringBuffer(StringBuffer sb) {
  sb.append(" and some more");
}
public static void main(String[] args) {
  StringBuffer sb("A text");
  changeStringBuffer(sb);
  // this one gives "A text and some more"
  System.out.println(sb.toString());
}
In place of StringBuffer, often the simpler an not-thread-safe class StringBuilder can be used. Swapping, though, does not work:
public static void swap(StringBuffer a, StringBuffer b) {
  StringBuffer c = a;
  a = b;
  b = c;
}
does not really do anything. BTW ... when concatenating Strings, it is better to use StringBuilder and .append, as
String s;
for (.;.;.) s += something; 
is pretty inefficient; for each +=, the String's content needs to be copied into a new instance that has a bit more space at the end for "something". Results in O(n^2) "efficiency", while StringBuilder only needs to get more memory when an internal limit is reached.

C++Threading

OpenThreads as part of OpenSceneGraph contains a number of nice classes for working with threads in C++, using a Posix implemention (*n*x), or the Win32 or Solaris specific one. It is also possible to compile just the three classes that the threading stuff is comprised of, combine it with the appropriate headers, and use it. One thing is missing, though ... an implementation of the "resource acqusition by constructing" pattern. As C++ does not have a "finally" construct, the best solution to ensure a used mutex is freed in all circumstances (earlier return, exceptions, SEGV, ...) is to create a class that locks the mutex on construction and frees it on destruction, and to instantiate this class when needing the mutex (on the stack, of course, not with new).

class  LockIt {
public:
  LockIt(Mutex& mutex) : mMutex(mutex) { mMutex.lock(); }
  virtual ~LockIt() { mMutex.unlock(); }
private:
  Mutex& mMutex;
};
A Mutex called mMutex is defined somewhere; then, you can use it
{
LockIt(mMutex);
// work locked
}
// lock on mMutex automatically released
The thread helpers that are part of the boost class library are far more powerful in this direction, they also contain various lock acquisition classes. Boost will also be part of the next release of the C++ standard ... on the other hand, it is really large (a thousand header files, if I counted right), and not that easy to use ...

C++-Documentation: Links

Interesting documentation links about C++

Tutorials

LibStdC++

Threading

Resource allocation

Humor

java.util.ArrayList != std::list

When using "lists" in Java, ArrayList is usally the choice. When using list contructs in C++, using std::list is usually not a good idea, as it is implemented as linked list, and therefore all indexed acesses (list[i]) take linear time, and an iteration such as

for (int i=0; i<list.size(); i++) {...}
takes O(n^2)! (Of course, one should not do this in StdC++/STL anyway, but use the iterators.) Thus, std::vector should be used in most cases. Only exception: regularly adding elements somewhere inside the list, which is far more efficient in a (doubly) linked list.