Java

Annotation based migrations for XStream

While looking for a simple way to migrate outdated Java models serialized with XStream I found XMT from Robin Shine, described at Migrate Serialized Java Objects with XStream and XMT. Hell, this was exactly what I was looking for! Instead of fiddling with multiple outdate Java classes that only exists for legacy reasons, just modify the DOM document before unmarshaling the thing with XStream!

JasperReports: Append an In-Report ToC without Scriptlets

Whenever you want to add a Table of Contents to your Jasper Report you have a problem, because there is no build-in function to do this. Most solutions suggest to derive an own Scriptlet class, use subreports or provide a custom data source.

Let me add another quick & dirty solution that requires no external resources, not even the Groovy library. It works with pure embedded Java code, at least as long you're ok with the very simplified layout of this solution, and do not require to have the ToC at the beginning of your report. And furthermore, it is pretty simple.

First, create a new parameter of type java.lang.StringBuilder:

<parameter name="toc" class="java.lang.StringBuilder" isForPrompting="false">
	<defaultValueExpression><![CDATA[new StringBuilder()]]></defaultValueExpression>
</parameter>

This parameter called toc will be filled with the table of content during the rendering of the detail sections. You may add markup if you want to.

Next, on the summary page, print the content of this parameter. I'll use HTML formated strings, here:

<statictext>
	<reportElement x="0" y="0" width="540" height="20"/>
	<textElement verticalAlignment="Middle">
		<font size="14" isBold="true" isItalic="true"/>
	</textElement>
	<text><![CDATA[Table of Contents]]>
</staticText>
<textField isStretchWithOverflow="true">
	<reportElement x="28" y="30" width="471" height="20"/>
	<textElement markup="html">
		<font fontName="Monospaced" size="8"/>
	</textElement>
	<textFieldExpression><![CDATA[$P{toc}.toString()]]></textFieldExpression>
</textField>

Maybe you noticed that I use a monospace font here. This will be explained later.

Whereever you want to have a new entry (e.g. in the detail band or within a group header) add a new text field and put the following expression into it:

$P{toc}.append(
	$F{section}.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;")
		+ "<font color='#999999'>"
			/* Fill the string with up to 80 dots */
			+ new String(new char[80 - Math.min($F{section}.length(), 80)]).replaceAll(".", ".")
		+ "</font>"
		+ $V{PAGE_NUMBER}
		+ "<br>"
) == null ? "" : ""

This works since StringBuilder.append returns an object (itself). It won't be visible since the expression will result in an empty string in any case.

In this example, I want to use the field "section" as an index. Because the resulting string will be formatted using html markup we have to escape "<" as "&lt;", ">" as "&gt;" and "&" as "&amp;". In the next lines, you see the reason why I decided to use a monospace font for the ToC: the section name should be followed by up to 80 grey dots and the page number.

Since you cannot use loops within JasperReport's expressions (at least not without Groovy) I used the trick to create a new String containing the required number of 0x0 characters and replace all characters (the first parameter of String.replaceAll is a regular expression) with dots.

Java: process http.proxyUser and http.proxyPassword

Some tutorials suggest to use the system properties http.proxyUser and http.proxyPassword to get proxy authentication, but that won't work since - in contrast to http.proxyHost and http.proxyPort - these properties will not be processed by Java's HttpURLConnection.

Other suggest to use a custom default Authenticator. But that's dangerous because this would send your password to anybody who asks.

Evaluate structured code in JasperReports

JasperReports is a library which can be used to fill reports from Java applications or just create simple PDFs. It allows you to not only use static output strings but also Groovy expressions. Sadly, this is restricted to simple expressions that result in a value and don't generate multiple class files at compile time.

For example, you could use the following expression to print different values depending if your document has more or less than 10 pages:

Java: Model-View-Controller without memory leaks

When doing MVC programming in Java, there is a problem that most people don't know about. I've ignored it myself much too long. The problem is that when you bind a model class to an UI component you will get a giant memory leak.

What happens?

Well, imagine a model class supporting listening for property changes. A simple example might look like this (I extend from PropertyChangeSupport here so that I don't have to delegate all the methods, normally you wouldn't do so, of course):

Eclipse: Keine Bevormundung durch Ubuntu

Unter Ubuntu fragt Eclipse beim Starten nicht, welcher Workspace verwendet werden soll, sondern wählt immer $HOME/workspace - selbst wenn in den Einstellungen explizit festgelegt wurde, dass er fragen soll.

Woran das genau liegt, kann ich nicht sagen, aber es hat wohl was mit der verwendeten Java-VM zu tun, der Standard ist java-gcj. Umgehen lässt sich dieses Problem, indem die Pakete sun-java6-jdk bzw. sun-java6-jre installiert werden und die Verwendung dieser mithilfe der Umgebungsvariablen JAVA_HOME erzwungen wird: