Thursday, October 25, 2007

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, !".

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.

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.

Sunday, October 21, 2007

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

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.

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

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

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

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 ;-)

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.cc

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

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

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!

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

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

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:

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.

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

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

Resource allocation

Humor

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.