<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dahamwirdensalat &#187; Java</title>
	<atom:link href="http://dahamwirdensal.at/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://dahamwirdensal.at</link>
	<description>Everyone's a winner baby that's the truth</description>
	<lastBuildDate>Tue, 20 Oct 2009 12:30:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Java Coding advice meets Hagakure meets a badly translated taiwanese Users Manual</title>
		<link>http://dahamwirdensal.at/2006/10/java-coding-advice-meets-hagakure-meets-a-badly-translated-taiwanese-users-manual</link>
		<comments>http://dahamwirdensal.at/2006/10/java-coding-advice-meets-hagakure-meets-a-badly-translated-taiwanese-users-manual#comments</comments>
		<pubDate>Mon, 09 Oct 2006 06:06:56 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/10/java-coding-advice-meets-hagakure-meets-a-badly-translated-taiwanese-users-manual/</guid>
		<description><![CDATA[ 	Look what just came into my inbox:

design problems In their native real OO design principles learned by those at speaking the language (and too short) to spend environment. In other
 You&#8217;re not and experience of others, support in your own code. You&#8217;ll easily counter with your With Design Patterns, Facade, Proxy, and Factory that [...]]]></description>
			<content:encoded><![CDATA[<p> 	Look what just came into my inbox:</p>
<blockquote><p>
design problems In their native real OO design principles learned by those at speaking the language (and too short) to spend environment. In other<br />
 You&#8217;re not and experience of others, support in your own code. You&#8217;ll easily counter with your With Design Patterns, Facade, Proxy, and Factory that you can hold your<br />
 someone struggles of patterns with others what to expect&#8211;a visually-rich you don&#8217;t want to the next time you&#8217;re</p>
<p> &#8220;secret language&#8221; a design paddle pattern. want to see how you get to take In their native design problems, and better<br />
Singleton isn&#8217;t as simple as it<br />
to use them (and when Best of all, in a way that won&#8217;t format designed for the way and experience of others, environment. In other</p>
<p> the next time you&#8217;re so that you can spend you have. You know of Design Patterns so Design Patterns, you&#8217;ll avoid how patterns are<br />
real OO design principles your brain works. Using the same software on your team.<br />
 of Design Patterns so design problems<br />
 or on the real relationship</p>
<p> so that you can spend </p>
<p>But you don&#8217;t just alone. At any given moment, You want to learn the and Adapter. With Head First<br />
 You&#8217;re not and experience of others,<br />
 you don&#8217;t want to</p>
<p> a book, you want </p>
<p>environment. In other you don&#8217;t want to design problems about inheritance might<br />
 the &#8220;Trading Spaces&#8221; show. applications. You<br />
 the &#8220;Trading Spaces&#8221; show.</p>
<p> Decorator is something from </p>
<p> principles will help (and too short) to spend support in your own code. of patterns with others<br />
put you to sleep! We think &#8220;secret language&#8221; how patterns are<br />
 you want to learn the of the best practices Head First book, you know</p>
<p> Most importantly, else. Something more the next time you&#8217;re at speaking the language to do instead). You want science, and learning theory, You&#8217;ll easily counter with your<br />
 when to use them, how<br />
 you have. You know a book, you want<br />
 of patterns with others<br />
 someone struggles the latest research in<br />
 Java&#8217;s built-in pattern</p>
<p> who&#8217;ve faced the deep understanding of why the same software reinvent the wheel matter&#8211;why to use them,<br />
 so you look to Design Design Patterns, you&#8217;ll avoid , and how to exploit same problems.<br />
 In a way that lets you put support in your own code. you don&#8217;t want to environment. In other real OO design principles<br />
 words, in real world<br />
 same problems.<br />
 look &#8220;in the wild&#8221;. used in the Java API the embarrassment of thinking texts. If you&#8217;ve read a to know how they </p>
<p> sounds, how the Factory Singleton isn&#8217;t as simple as it Most importantly,</p>
<p> to use them (and when be wrong (and what<br />
so that you can spend (and too short) to spend own with your co-worker on your team.<br />
 you want to learn the or on the real relationship<br />
 you get to take</p>
<p> you have. You know
</p></blockquote>
<p>The sound advice burried into this little gem needs a lot of contemplation before its wisdom is fully absorbed.</p>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/10/java-coding-advice-meets-hagakure-meets-a-badly-translated-taiwanese-users-manual/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apple&#8217;s iTunes podcast directory uses the Jakarta Commons HTTPClient</title>
		<link>http://dahamwirdensal.at/2006/07/apples-itunes-podcast-directory-uses-the-jakarta-commons-httpclient</link>
		<comments>http://dahamwirdensal.at/2006/07/apples-itunes-podcast-directory-uses-the-jakarta-commons-httpclient#comments</comments>
		<pubDate>Thu, 13 Jul 2006 08:00:05 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Net]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/07/apples-itunes-podcast-directory-uses-the-jakarta-commons-httpclient/</guid>
		<description><![CDATA[ 	While idly skimming through our webserver&#8217;s access log, I stumbled across this:
17.230.17.111 - - [13/Jul/2006:09:16:07 +0100] "HEAD /swingerklub/podcast.pdc HTTP/1.1" 200 - "-" "Jakarta Commons-HttpClient/3.0"
And a whois 17.230.17.111 tells us:
OrgName:    Apple Computer, Inc.
OrgID:      APPLEC-3
Address:    20740 Valley Green Drive, MS32E
City:      [...]]]></description>
			<content:encoded><![CDATA[<p> 	While idly skimming through our webserver&#8217;s access log, I stumbled across this:</p>
<pre><code>17.230.17.111 - - [13/Jul/2006:09:16:07 +0100] "HEAD /swingerklub/podcast.pdc HTTP/1.1" 200 - "-" "Jakarta Commons-HttpClient/3.0"</code></pre>
<p>And a <code>whois 17.230.17.111</code> tells us:</p>
<pre><code>OrgName:    Apple Computer, Inc.
OrgID:      APPLEC-3
Address:    20740 Valley Green Drive, MS32E
City:       Cupertino
StateProv:  CA
PostalCode: 95014
Country:    US</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/07/apples-itunes-podcast-directory-uses-the-jakarta-commons-httpclient/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You&#8217;re not supposed to see that anyway</title>
		<link>http://dahamwirdensal.at/2006/06/youre-not-supposed-to-see-that-anyway</link>
		<comments>http://dahamwirdensal.at/2006/06/youre-not-supposed-to-see-that-anyway#comments</comments>
		<pubDate>Thu, 08 Jun 2006 15:47:46 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Timesheet]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/06/youre-not-supposed-to-see-that-anyway/</guid>
		<description><![CDATA[ 	Well, if it isn&#8217;t our overprotective mommy again. Sometimes, this Overprotection against technology is comfortable and gives a warm, snuggly feeling. And sometimes, it&#8217;s just brain dead. Whatever your personal opinion about iCal may be, you will have to agree that it falls into the latter category. I always suspected as much (at least [...]]]></description>
			<content:encoded><![CDATA[<p> 	Well, if it isn&#8217;t our <a href="http://www.apple.com">overprotective mommy</a> again. Sometimes, this Overprotection against technology is comfortable and gives a warm, snuggly feeling. And sometimes, it&#8217;s just brain dead. Whatever your personal opinion about <a href="http://www.apple.com/macosx/features/ical/">iCal</a> may be, you will have to agree that it falls into the latter category. I always suspected as much (at least since I found out that you cannot drag an eMail message from <a href="http://www.apple.com/macosx/features/mail/">Mail</a> to the ToDo list), but never paid too much attention to it. iCal looks nice, the name is confusing (because iCal is also the abbreviation of the file format it is using), it is simple and does what it should do.<br />
This impression might change if you have to interact with it. Meaning: Exchange data with it. At first, you might be as <em>naive</em> as I am, and think: <em>Well, it&#8217;s just a bunch of files. You can read and write them, so what could be the problem?</em><br />
First of all, this is correct: It is just a bunch of files. The question is: Where are they? On OS X 10.3, they are in <code>~/Library/Calendars/</code>. On OS X 10.4, every iCal file has its own folder inside <code>~/Library/Application Support/iCal/Sources</code>, complete with additional files, indices, and a list of all available calendar files.<br />
Supposing you solved the problem of finding the files you want to read from or write to, you will face another one:<br />
iCal reads the calendar files (<code>.ics</code>) only on startup. For everything else, it uses its own, probably indexed, version that is burried somewhere in the caches part of the Library. That means that if your application changes the contents of the file, these changes will not be reflected in the iCal user interface.<br />
Even better: Whenever iCal quits normally, it writes the contents of its own cache file back to the original calendar file, reverting all changes you made to the file.<br />
To be fair, Apple <em>does</em> support synchronization between iCal and other applications through a <em>Synchronization conduit</em> (basically what the iPods are doing). But of course, there is no Java support for this method.<br />
This leaves me with the not very attractive option of using a HTTP server inside a desktop application to export data into a different desktop application running on the same machine. I <em>think</em> I&#8217;m kidding, but actually, I&#8217;m not sure &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/06/youre-not-supposed-to-see-that-anyway/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Silent, but working</title>
		<link>http://dahamwirdensal.at/2006/05/silent-but-working</link>
		<comments>http://dahamwirdensal.at/2006/05/silent-but-working#comments</comments>
		<pubDate>Mon, 29 May 2006 18:02:24 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Timesheet]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/05/silent-but-working/</guid>
		<description><![CDATA[ 	It&#8217;s been a while since I last wrote something about Timesheet. Sometimes, silence is a sign of work. The reporting and iCal code was thrown out. Relunctantly, I&#8217;ve taken up work on a caching mechanism that will make the startup of Timesheet much faster.
The user interface will present a cached version of the last [...]]]></description>
			<content:encoded><![CDATA[<p> 	It&#8217;s been a while since I last wrote something about Timesheet. Sometimes, silence is a sign of work. The reporting and iCal code was thrown out. Relunctantly, I&#8217;ve taken up work on a caching mechanism that will make the startup of Timesheet much faster.<br />
The user interface will present a cached version of the last state of the interface, while the actual data from the database is loaded in the background. It&#8217;s a bit tricky, because I&#8217;ll have to handle user-input in a queue, while keeping the fact that you&#8217;re not actually working on your data completely transparent. I hope I&#8217;ll be able to finish this in this week.</p>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/05/silent-but-working/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taking a full Swing at sanity</title>
		<link>http://dahamwirdensal.at/2006/05/taking-a-full-swing-at-sanity</link>
		<comments>http://dahamwirdensal.at/2006/05/taking-a-full-swing-at-sanity#comments</comments>
		<pubDate>Fri, 05 May 2006 14:18:14 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/05/taking-a-full-swing-at-sanity/</guid>
		<description><![CDATA[ 	If somebody would actually have the nerve to compile a list of all technologies that most likely have been created simply to annoy people, I&#8217;d like to suggest Swing to be somewhere in there. Maybe Number 1 or 2, but definitely in the Top 5.
And I&#8217;m not even talking about the LayoutManager from Hell [...]]]></description>
			<content:encoded><![CDATA[<p> 	If somebody would actually have the nerve to compile a list of all technologies that most likely have been created simply to <em>annoy</em> people, I&#8217;d like to suggest <em>Swing</em> to be somewhere in there. Maybe Number 1 or 2, but definitely in the Top 5.<br />
And I&#8217;m not even talking about the <em>LayoutManager from Hell</em> (also known as GridBoxLayout to its more intimate enemies), but just those little quirks that make working with Swing so difficult.<br />
It took me the better part of two afternoons to figure out the answer to this question:</p>
<blockquote><p>What do you do when you want to replace a component in a Window with another one?</p></blockquote>
<p><em>Answer 1</em><br />
Use <code>component.repaint()</code> on the parent of the changed component. After all, the component should be repainted as soon as possible after this call. Of course, this is a rhetorical entry, because I have to build up some drama.<br />
<em>Answer 2</em><br />
Use <code>component.invalidate()</code> on the parent of the changed component.<br />
This should also invalidate all parents of the component, so everyone should repaint itself. Sounds fine, but it&#8217;s also not working.<br />
<em>Answer 3</em><br />
Both of them. Use <code>repaint()</code> and <code>invalidate()</code> liberally in the method that changes the component. Change the sequence of the calls, mix and shake it. Set this or that to <code>null</code>, just in case.</p>
<p>As you might have guessed by now, after I arrived at answer 3 (which, of course, is not the correct answer), I was rather furious. More or less by accident I discovered<br />
<em>Answer 4</em><br />
Use <code>component.revalidate()</code>.</p>
<p>As everyone will have guessed by now, <em>Answer 4</em> is correct. I don&#8217;t know why, but I&#8217;m sure there is a very plausible explanation for it.</p>
<p><em>Ceterum censeo LayoutManager esse delendam!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/05/taking-a-full-swing-at-sanity/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Where am I? Operating System detection with Java</title>
		<link>http://dahamwirdensal.at/2006/04/where-am-i-operating-system-detection-with-java</link>
		<comments>http://dahamwirdensal.at/2006/04/where-am-i-operating-system-detection-with-java#comments</comments>
		<pubDate>Mon, 24 Apr 2006 09:53:21 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/04/where-am-i-operating-system-detection-with-java/</guid>
		<description><![CDATA[ 	Cross-platform or not, sometimes it&#8217;s important to know on which operating system your program is running on (because you need to know where your jar file is, for example).
Maybe not the nicest way to do it, but working:
private static final String MAC_ID = "Mac";
private static final String WINDOWS_ID = "Windows";

private String OSIdentifier;
private boolean isMac;
private [...]]]></description>
			<content:encoded><![CDATA[<p> 	Cross-platform or not, sometimes it&#8217;s important to know on which operating system your program is running on (because <a href="/peter/2006/04/automatically-adding-version-information-into-a-java-manifest-file-with-ant/">you need to know where your jar file is</a>, for example).<br />
Maybe not the nicest way to do it, but working:</p>
<pre><code>private static final String MAC_ID = "Mac";
private static final String WINDOWS_ID = "Windows";

private String OSIdentifier;
private boolean isMac;
private boolean isWindows;
private boolean isUnix;

private String dataPath;
private String configPath;
private String jarPath;

private void init()
{
	OSIdentifier = System.getProperty("os.name");

	if (OSIdentifier.indexOf(MAC_ID) > -1)
	{
		isMac = true;
		dataPath = System.getProperty("user.home") + "/Library/Application Support/myProject/";
		jarPath = "./Contents/Resources/Java/";

	}
	else if (OSIdentifier.indexOf(WINDOWS_ID) > -1)
	{
		isWindows = true;
		dataPath = System.getProperty("user.home") + "\\myProject\\";
		jarPath = ".\\";
	}
	else
	{
		isUnix = true;
		dataPath = System.getProperty("user.home") + "/.myProject/";
		jarPath = "./";
	}

}</code></pre>
<p>Add getters and setters, and you&#8217;re good to go. Of course, you might further differentiate between different Unix systems according to your needs.</p>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/04/where-am-i-operating-system-detection-with-java/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically adding version information into a Java Manifest file with Ant</title>
		<link>http://dahamwirdensal.at/2006/04/automatically-adding-version-information-into-a-java-manifest-file-with-ant</link>
		<comments>http://dahamwirdensal.at/2006/04/automatically-adding-version-information-into-a-java-manifest-file-with-ant#comments</comments>
		<pubDate>Sun, 23 Apr 2006 12:38:20 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://homex.subnet.at/peter/2006/04/automatically-adding-version-information-into-a-java-manifest-file-with-ant/</guid>
		<description><![CDATA[ 	Version information is important for applications and  libraries alike. Somebody using your jar file (be it an application, a library or a part of a larger framework) should be able to tell which version of your program they are using. Equally, giving the users that information should be as little effort for the [...]]]></description>
			<content:encoded><![CDATA[<p> 	Version information is important for applications and  libraries alike. Somebody using your jar file (be it an application, a library or a part of a larger framework) should be able to tell which version of your program they are using. Equally, giving the users that information should be as little effort for the developer as possible. Some library authors solve this by creating versions of their libraries with the version information in the filename (for example, <code>avalon-excalibur-vm14-20020705.jar</code>, which happened to linger around in a lib directory I have open in my shell, so I used as an example), but this approach is not working very well for applications. Besides, using &#8220;versioned&#8221; filenames has its own problems (no drop-in replacement of newer versions because the classpath needs to be changed).</p>
<p>Another way to give the users informations about what version of a jar file they are using is to store it in the jar file itself, in a file called the <em>manifest</em>, which is present in all jar files.</p>
<p>This little tutorial shows you how to automatically generate the manifest for your jar file and access the information later on in your Java program (for example, in an &#8220;About&#8221; dialog). The insertion of the version information will be part of your automated build-process, and your Java application will read this information directly from the jar file. All you need is a text file containing the version name (or number). If you&#8217;re working with the subversion SCM, you can also easily add the current revision number to the jar file.</p>
<p>The main advantage of this approach is that version information (or any other information, for that matter) is stored in one place, and set at the time the jar file is created. No need for additional configuration files or hardcoded version identifiers in your classfiles.</p>
<p><span id="more-73"></span></p>
<p>Here is what you will need:</p>
<ol>
<li>The build tool <a href="http://ant.apache.org/" title="Apache Ant homepage">Apache Ant</a>.</li>
<li>A Mac, Linux, or other Unix system if you want to add subversion information to the jar file. (Sorry, I&#8217;m sure there is way to automatically get the revision information into ant on Windows, but I don&#8217;t know how because I don&#8217;t use Windows)</li>
<li>A text file containing the version information of your program.</li>
</ol>
<h3>Preparing your build</h3>
<p>If you&#8217;re using subversion for controlling your repository, you can also add the revision number of the build to the jar-file. To do this, we need a way to access the current revision of your repository.<br />
Create a shell script called getlatestrepoversion.sh containing the following:</p>
<pre><code>#!/bin/bash
echo  `svn info . | grep "Last Changed Rev" | awk '{print $4}'`</code></pre>
<p>and give it execute permission:</p>
<pre><code>chmod u+x getlatestrepoversion.sh</code></pre>
<p>If you don&#8217;t use subversion or don&#8217;t want that information in your jar-file, just don&#8217;t create that shell script, and remove all references to the ant task <code>svn-info</code> from the ant <code>build.xml</code> shown below.</p>
<p>The version number of your project (for example, &#8220;1.0&#8243;) is stored in a file called <code>build.properties</code>. Create this file, and set an <code>app.version</code> property in it:</p>
<pre><code>app.version=1.0</code></pre>
<p>Ant is controlled by a file called <code>build.xml</code>. By setting &#8220;targets&#8221;, ant will automatically perform tasks like compiling, creating JavaDocs or bundling up a distribution of your project.</p>
<p>Here is the complete <code>build.xml</code> you need for including build information into your jar file:</p>
<pre><code>&lt;?xml version="1.0"?&gt;

&lt;project name="myProject" basedir="."&gt;
	&lt;description&gt;buildfile for myProject&lt;/description&gt;

	&lt;!--
	This initializes the ${DSTAMP} and ${TSTAMP} ant properties.
	--&gt;
	&lt;tstamp/&gt;

	&lt;!-- This file contains informations about the build and is
	loaded automatically --&gt;
	&lt;property file="build.properties"/&gt;

	&lt;!-- set global properties for this build --&gt;
	&lt;property name="src" location="src"/&gt;
	&lt;property name="build"  location="classes"/&gt;
	&lt;property name="jar" location="jar"/&gt;

	&lt;path id="build-classpath"&gt;
		&lt;pathelement location="${build}"/&gt;
	&lt;/path&gt;

	&lt;patternset id="all-classes"&gt;
		&lt;include name="**/*.class"/&gt;
		&lt;exclude name="**/Test/**"/&gt;
	&lt;/patternset&gt;

	&lt;target name="init" depends="svn-info"&gt;
	&lt;!-- Create the build directory structure used by compile --&gt;
	&lt;mkdir dir="${build}"/&gt;

	&lt;/target&gt;

	&lt;target name="svn-info"&gt;
		&lt;exec executable="./getlatestrepoversion.sh" outputproperty="svnrevision"/&gt;
		&lt;echo&gt;Repository Version: ${svnrevision}&lt;/echo&gt;
	&lt;/target&gt;

	&lt;target name="compile" depends="init" description="compile the source " &gt;
		&lt;!-- Compile the java code from ${src} into ${build} --&gt;
		&lt;echo&gt;Compiling ...&lt;/echo&gt;
		&lt;javac srcdir="${src}" destdir="${build}" debug="on"&gt;
		&lt;classpath refid="build-classpath"/&gt;
		&lt;/javac&gt;
		&lt;echo&gt;Done.&lt;/echo&gt;
	&lt;/target&gt;

	&lt;target name="jar" depends="compile"&gt;
		&lt;mkdir dir = "${jar}"/&gt;
		&lt;manifest file="MANIFEST.MF"&gt;
			&lt;attribute name="Main-Class" value="your.mainClass"/&gt;
			&lt;attribute name="Class-Path" value="your,class,path"/&gt;
			&lt;!-- This line puts your username into the manifest.
			Maybe you don't want to do that. --&gt;
			&lt;attribute name="Built-By" value="${user.name}"/&gt;
			&lt;attribute name="Built-On" value="${DSTAMP}-${TSTAMP}"/&gt;
			&lt;!-- This property was set by the svn-info task --&gt;
			&lt;attribute name="Revision" value="${svnrevision}"/&gt;
			&lt;!-- This property comes from the build.properties file --&gt;
			&lt;attribute name="Version" value="${app.version}"/&gt;
		&lt;/manifest&gt;

		&lt;echo&gt;Building jar file.&lt;/echo&gt;
		&lt;jar jarfile="${jar}/${ant.project.name}.jar"
		  			manifest="manifest.mf"&gt;
                &lt;fileset dir="${build}/"&gt;
                        &lt;patternset refid="all-classes"/&gt;
                &lt;/fileset&gt;
        &lt;/jar&gt;
	&lt;/target&gt;

&lt;/project&gt;</code></pre>
<p>I&#8217;ve kept everything in it that you need to run the jar-task, so you can easily adopt it to your needs. If you already have a build.xml for your project and only want to add the parts that put the build information into your jar-file, here is what you need to do:</p>
<p>Make sure you call <code>&lt;tstamp/&gt;</code> prior to accessing the timestamp properties and call <code>&lt;property file="build.properties"/&gt;</code> before building the jar.<br />
Call the <code>svn-info</code> task before building the jar (preferable with a &#8220;depends&#8221; clause) and copy the part about the manifest from the <code>jar</code> target to your own file.</p>
<h3>Building the jar file</h3>
<p>Before calling <code>ant jar</code>, you need to update your working copy of the repository. Call <code>svn update</code> at the root of your project folder. This will sync the revision number of your working copy with the revison number of the repository. This has to be done even if you just committed a change, because the &#8220;global&#8221; revision number of the complete working copy will not be updated by a commit.<br />
Note that this will also update any files that have changes in the repository (which is the reason why it is not done automatically).<br />
Then, call <code>ant jar</code>. This will create a jar-file of your project containing the build information.</p>
<p>To verify that all went well, you can either look at the contents of <code>MANIFEST.MF</code> in your current directory, or unpack the created jar-file and check <code>META-INF/MANIFEST.MF</code>.</p>
<h3>Accessing the manifest-information in your Java program</h3>
<p>By now, the build information is contained in the jar-file and you can find out what version the jar file is used by extracting its contents and looking at the MANIFEST.MF inside the jar. But wouldn&#8217;t it be nice if you could access that information programmatically to show the user the version and build information? This little piece of code does exactly that:</p>
<pre><code>public void readManifest()
{
	try
	{
		JarFile jar = new JarFile("./yourJarFile.jar");
		Manifest manifest = jar.getManifest();

		Attributes attribs = manifest.getMainAttributes();

		builtDate = attribs.getValue("Built-On");
		builtBy = attribs.getValue("Built-By");
		version = attribs.getValue("Version");
		revision = attribs.getValue("Revision");

	}
	catch (IOException e)
	{
		log.error("Cannot read jar-file manifest: " + e.getMessage(), e);
	}
}</code></pre>
<p>Two notes on this method: First, it assumes that yourJarFile.jar is in the current working directory (<code>./</code> on Windows and Unix). On the Mac, this is not the case; the jar-file will be at <code>./Contents/Resources/Java/yourJarFile.jar</code>.<br />
Second, the method will throw an IOException if the jar file could not be found or not read for any other reason. This will most likely be the case if you launch your program from within an IDE (for example, while working on it). Therefore, we catch the Exception immediately, so your program stays usable even when not started from the jar file.</p>
<p>The variables set are private members of a &#8220;Config&#8221; class that can be accessed via getters from other parts of the program (for example, an &#8220;about&#8221; dialog).</p>
]]></content:encoded>
			<wfw:commentRss>http://dahamwirdensal.at/2006/04/automatically-adding-version-information-into-a-java-manifest-file-with-ant/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
