Wednesday, February 27, 2008

Qype video

Qype [kwaip] has posteda nice video that explains how its name is pronounced. German only. It is supposed to be shown in German cinemas soon. Will be interesting to see it there and to see how people react.

Tuesday, February 26, 2008

RHQ SVN running at full speed

When we first announced RHQ, we put the state of our internal svn repository at RHQ, but did not start right away committing new stuff into it.
Last night we switched over to the RHQ svn and added all the stuff that was developed since the first cut over.
So expect lots of changes going into it from now on.
If you don't want to check out the source, but just browse around, you can use the source viewer at http://www.rhq-project.org/svn.php.

Don't forget to checkout the documentation in the forums.

You can also meet developers on #rhq at irc.freenode.net.

Tuesday, February 19, 2008

Be careful with @OneToOne and lazy loading

When modelling an entity one sometimes wants to have information in a separate table even if it would exist only one time for a given entity. Think of a 1:0...1 composition. This could be handled as embedded in the primary entity, but perhaps you don't want to do this as the dependent object is huge and you don't always need it. The dependent table could even live in a different table space for that reason. Or just for relational normalization reasons.

For the @xxxToOne relations, JPA 1.0 spec sees Eager loading as default. One can give a *hint* that the dependend end should be lazily loaded, but this is only a hint.

Now when you have an optional @OneToOne relation, Hibernate (at least) needs to do an additional select for that relation to find out if the dependend object is null or not. For a mandatory (1..1) relation it can just install a proxy to lazily load the relation, but this is not possible for 1...0..1.
See e.g. http://www.hibernate.org/162.html for an explanation.

Thursday, February 14, 2008

Project RHQ is here

At JBossWorld in Orlando, Red Hat anounced together with Hyperic the new Project RHQ. Why do I write about it?
Lets quote from the press release:
It is anticipated that the RHQ project will serve as the code base for JBoss Operations Network v2.0 (JON 2.0), due out in the Spring of 2008.

Well, I was for over a year working on JON 2.0 and will continue to do so. So this is a big step for me and the others of our team.

The two press releases:
Hyperic press release
Red Hat press release

Code is available at http://www.rhq-project.org/svn.php and anonymous svn access has been set up as well.

Be sure to check out http://www.rhq-project.org/ and start contributing today :-)

Friday, February 01, 2008

Add mod_jk to the Apache that comes with Tiger

Mac OS X Tiger (and Leopard, perhaps also earlier versions) come with an Apache httpd installed.
If you want to use this as frontend for a Tomcat or JBoss with embedded tomcat, you need to install mod_jk.

The canonical way is to use the macports port. Unfortunately will this a) try to install apache2 and b) fail building (at least for me).

Fortunately there is a blog entry out there that explains how to do it by hand.

Note, that the link to the apache download is outdated. The best is to go to the root of the dowloads and just download the latet version.
When you are using mo_jk in front of a embedded tomcat in JBossAS, you also don't need the workers.tomcat_home directive in the config file.

Ah, and when this works, don't forget to trim down the loglevel in httpd.conf from trace to info. Else you will end up with gigabytes of logs.

JkLogLevel info

Wednesday, January 30, 2008

Ignore target folders in eclipse

In Eclipse when you press Command-Shift-R (Open Resource), you end up seeing the same resource a few times -- when it e.g. gets copied into a location in the workspace by your build tool (e.g. maven, ant).

I was looking for a solution for some time now and way playing with working sets for this purpose.
Rob Mayhew obviously has one:
http://robmayhew.com/eclipse-ignore-folder/

Now the "only" thing left to do is to mark those target directories as derived -- after each clean up of those folders.

Luckily there is a project dash in Eclipse that can use javascript to do this.
Someone on the net even wrote the right script

Sunday, January 13, 2008

Mac apps runtime config

Much of an application on a Mac is configured by a file called Info.plist. You can find the file when
you right click on an application and choose "Show packet content" and descend down in the Content folder.

Apple has a page about all the key/value pairs at http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/PListKeys.html.

I was looking for a way to disable the dock icon and Main menu from a "StatusBarApp" (Apple calls them Agents IIUC). But without knowing the right terminology, this is hard to find :)

Tuesday, January 08, 2008

Cocoa: Preferences - and Binding

Since Mac OS X 10.3 there is a new "Binding" mechanism. The idea behind this is to e.g. have an observer pattern for the enablement of GUI elements or to read and store preferences without coding. To use this, you need to pull the NSUserDefaultsController from the controller palette in InterfaceBuilder into your app. In the inspector for a field, you can then go to the "bindings" pane and bind the values (shown here for a NSTextField, but applies to other GUI elements like checkboxes as well):



Bind to: should be set to the NSUserDefaultsController. For the controller key, you can leave the values. Model key path finally contains the key in the preferences. Depending on the kind of GUI element, the right data type will be choosen automatically.

The technique of binding basically allows to provide a preferences panel without any (Objective-C) coding to set and store the values -- very nice.
It is still a good idea to provide defaults for the settings as described in the previous post.


Update: I just found a nice article from Apple describing all this as well.

Friday, January 04, 2008

Cocoa: Preferences

Sometimes you want to save some user preferences for your app. Luckily there is good support for this in Mac OS X.
Perferences are key-value pairs that can be stored in the filesystem. The system works in multiple layers which means that if a key is not found in an upper layer, it will be searched in the layer below. Layers are: command line, application, global, language and default. This is means also that you don't need any additional code to see if a property is given on the command line or in the preferences etc - that is all transparent.
A good idea is to always provide the fallback values, so your code never needs to check if a preferences key is actually present or not.

Before your preferences show up in the Filesystem as user database under your choosen id, you have to fill the program id in Info.plist at:

<key>CFBundleIdentifier</key>
<string>XXX</string>

With the XXX the prefernces store would be ~/Library/Preferences/XXX.plist

An easy approach to set up the defaults if you only have a few preferences items is:

NSUserDefaults *preferences = [[NSUserDefaults standardUserDefaults] retain];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
  [NSNumber numberWithInt:11] ,@"interval",
  @"127.0.0.2" , @"targetAddr",
  NO, @"logEvents",
  @"osa:@shimoUp.aplescript", @"upScript",
  @"osa:@shimoDown.aplescript", @"downScript",
  nil ]; // terminate the list
[preferences registerDefaults:dict];


If you have more than a few items, it is easier to provide a defaults file in the app bundle and load this instead:

NSUserDefaults *preferences = [[NSUserDefaults standardUserDefaults] retain];
NSString *file = [[NSBundle mainBundle]
  pathForResource:@"Defaults" ofType:@"plist"];

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:file];
[preferences registerDefaults:dict];


After this is done, reading preference values is easy:


NSString *someString = [preferences objectForKey:@"targetAddr"];
int interv = [preferences integerForKey:@"interval"];

You might want to use the respective xxxForKey message depending on the type of preferences values.

Storing modified values is equally easy:

[preferences setInteger:someInt forKey:@"interval"];
[preferences setObject:someString forKey:@"targetAddr"];


The documentation for NSUserDefaults states that it will store the modifications from time to time to the underlying filesystem object, but I found it better to explicitly call [preferences synchronize] to trigger this.

Friday, December 28, 2007

Cocoa: Timed methods

Sometimes one wants to run a job a regular or scheduled times. One option would be to start a loop that runs until some abort condition is reached and that sleeps after the job is done. This is easily done, but has the big disadvantage to block the GUI while it is sleeping.
A better alternative is to set up a timer that calls you back from time to time. Cocoa offers the NSTimer class for this. It offers a wealth of methods to set up the timer and insert it into the RunLoop. The timer will then send from time to time a message to a method of your app that does the job.
It is actually easy to create the job. First you need to decide which method will be notified. In our example here it is - (void) runIt (with no arguments).
The code to set up the timer could then look like this:

NSTimer *timer;
timer = [NSTimer scheduledTimerWithTimeInterval:10.0
  target:self
  selector: @selector(runIt)
  userInfo:nil
  repeats: YES];

So this one schedules the execution of the runIt method of the same class the timer is created in, to repeat every 10 seconds.
Simple.
To cancel the timer again, one just has to send it an invalidate method:
[timer invalidate]

I was first experimenting with scheduledTimerWithTimeInterval:invocation:repeats: but for whatever reason it did not work, even if the timer said it is valid. But the above works well for me and is even easier.

Some Mac coding ... finally

I did some coding on Mac OS X lately. Basically the first time some real stuff besides just firing Xcode and InterfaceBuilder and closing them after some poking around.

At first it feels somewhat strange to code in Objective-C, given that I mostly did Java coding for the last five years, but then it feels good again. I am writing 'again' on purpose, as the whole programing is like it was over ten years ago on the NeXT.

I will try to put some stuff online, as I did fight against some obstacles and want to share the results.

Saturday, December 08, 2007

Small Applescript to make iTunes play

I recently put my Mac mini into a server room and am running it headless now.
As this one also has the iTunes library and the connection to the stereo, I was using VNC to connect to it and to start and stop iTunes. Of course that is cumbersome.
So I googled a little on "applescript" and "iTunes" and found this wonderful site.

Using the information on it I was able to come up with this script, that I saved as playTunes.scpt

tell application "iTunes"
if player state is paused then
play user playlist "a_Ungespielt"
return "Playing"
else
pause
return "Stopped"
end if
end tell


It will play the contents of a playlist called "a_Ungespielt" if iTunes is paused and stop playing otherwise.

I can now just log into the mini and start/stop playing with "osascript playTunes.scpt".

Saturday, December 01, 2007

Marlene is standing on her own


Marlene is growing well. She is eight months old now and since three weeks, she is able to sit up on her own. She is not yet able to crawl on arms and legs, but she is already moving around quite a bit.

Today she was for the first time able to stand up on her own by holding the bars of her bed and pulling herself up. She was totally happy and excited - as we have been as well

Wednesday, November 21, 2007

Oracle surprise

I was hunting an issue where inserting an empty string (not null in Java, but with String.lenght()==0) resulted in a constraint violation exception. The column was a varchar2 one and indeed marked as not null.

I asked some people that should know (including a former DBA) and everyone told me that "" != null - always.

Digging around I found the following in an Oracle manual:

Note: Oracle Database currently treats a character value with a length of zero as null. However, this may not continue to be true in future releases, and Oracle recommends that you do not treat empty strings the same as nulls.


So in this case "" == null.

It is ok if one knows it and one can work around, but it came as surprise to me and others.

Tuesday, November 20, 2007

Broken ixus

About one and a half years ago I bought myself a Canon Digital Ixus i Zoom. After two weks, the camera was broken, as the lens protection lids were just lying in the lens tube. I had the camera sent to Canon and they repaired it on warranty.
The camera worked well - until recently when I had the same issue again. Googling around indicated that this time the repair would be expensive.



After the camera was just lying around, I thougt "why don't I just remove the broken parts and try if it works again?"

Here is what worked for me.
I take no responsability whatsoever if your camera breaks, you hurt yourself or your dog runs away.
Continue reading at your own risk


So I took tweezers to try to remove them. As this was not soo easy I shaked the lens tube a bit and found out that I could just remove the cover.

The next image shows the parts that fell out


This closeup of the front shows an axis (red), a slider (green) and a hole (blue)


Put the one cover thingy with the hole marked in red on the axis and the hole marked in green on the slidrer. The teeth must be facing the hole marked in blue. Then put the other thingy in place with its little axis in the hole marked in blue and the teeth mathing those of the other one.


The result should look like in the next picture:



Or when you switch the camera on:


Now it is time to clip the grey plastic ring back on. There is basically only one way to do it right:



After that put the metal tube/front cover back on it and carefully apply some preasure to it. Volia the result:

Wednesday, November 14, 2007

Hyperic and Red Hat cooperate

Red Hat / JBoss built the JBoss ON 1.x product on the base of code from Hyperic. Now the two companies
are going to collaborate on that.

Why do I write that? Because I am part of the JBossON team :)

Friday, October 12, 2007

Use == for Enum comparision

I was recently running FindBugs over some Java5 based code and found some places where FindBugs was complaining that two Objects compared with equals() are not of the same type.
Closer inspection showed that this have been Enums in most cases. The IDEs did not warn here and maunal code inspection also does not directly show the issue.
Luckily with enums, you can use == to compare them. And then it gets obvious:




Just a small little change in habits, but it helps a lot.

JIRAClient is cool

Recently we at JBoss® received licenses for JIRAClient. It is a cool desktop app (written in Java) that serves as a frontent to Atlassians JIRA bugtracking sytem. One of the nicest features here is offline mode: JIRAClient is ablw to download issues to its local database, so you can work offline and upload changes later on.
The staff at Almworks is very responsive in the forums and also open to suggestions.

If you are using JIRA on an daily basis, then you should definitively check out JIRAClient.

Thursday, October 11, 2007

pg_stat_activity is your friend

PgAdmin for postgres has a nice feature called "Server status". It is great if you sit in front of a GUI.
But if you want to do some remote work or tell a customer to report that server status, it is not quite the right thing.

But at the end, pgAdmin is only doing

select * from pg_stat_activity order by procpid;


This will show you all client connections together with the command they are currently executing.

Tuesday, September 11, 2007

NPE due to autoboxing

One of the nice features of Java 5 is autoboxing. I guess everyone remembers the hassle of calling Integer.intValue() to convert from Integer to int.

Now can you guess what the following code does when you call FB.foo()?

public class FB
{
public void foo()
{
int x;
x = bar();
System.out.println("X is " + x);
}

public Integer bar()
{
return null;
}
}


Yeah, it is throwing a NullPointerException in the assignment x = bar() because bar() is returning null and the implicit bar().intValue() is thus throwing the NPE. Without autoboxing, this is much more evident.

Unfortunately it seems like FindBugs and other tools are not (yet) able to detect this (actually in my test code, FindBugs was not even able to detect the NPE in teh explicit call).