Tuesday, December 16, 2008

System.Net.HttpListenerException: Access Denied Windows 2008

To solve this problem:

Login as Administrator and run cmd or execute runas /user:DOMAIN\Administrator cmd

Execute the following line (change the URL and the user)

netsh http add urlacl url=http://+:8081/Service user=DOMAIN\user

Thats it.

Friday, December 12, 2008

Encrypting a String in C# (.Net)

There are many options to encode a string in C# (.Net).

Here is mine using TripleDES encryption.

using System;
using System.IO;
using System.Security.Cryptography;

namespace StringEncrypter
{
internal class Program
{
private static ICryptoTransform _decryptor;
private static ICryptoTransform _encryptor;

private static void Main()
{
var TDES = TripleDES.Create();

TDES.GenerateIV();
TDES.GenerateKey();
_encryptor = TDES.CreateEncryptor();
_decryptor = TDES.CreateDecryptor();

byte[] encrypted = Encrypt("secret string");
string decrypted = Decrypt(encrypted);
Console.WriteLine(decrypted);
}

private static byte[] Encrypt(string plain)
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream =
new CryptoStream(memoryStream, _encryptor, CryptoStreamMode.Write))
using (StreamWriter writer = new StreamWriter(cryptoStream))
{
writer.Write(plain);
}
return memoryStream.ToArray();
}


}


private static string Decrypt(byte[] encrypted)
{

using (MemoryStream memoryStream = new MemoryStream(encrypted))
using (CryptoStream cryptoStream =
new CryptoStream(memoryStream, _decryptor, CryptoStreamMode.Read))
using (StreamReader reader = new StreamReader(cryptoStream))
{
return reader.ReadToEnd();
}
}
}
}

Tuesday, October 21, 2008

Introduction Into Unit Testing Using Visual Studio And NMock

I posted some notes on Unit Testing with Visual Studio and NMock here:

http://docs.google.com/View?docid=dc5v867t_140cr94fqfj

I have some problems to get the formatting right in Blogger. So this link is a better read.

Monday, October 6, 2008

Discussing Software Design Decisions

Having joined a new development team recently, I found myself frequently discussing rather trivial design issues with the other team members.

I do enjoy this discussions a lot and they do provide value to the project as the design is thought through thoroughly by several people.

Nevertheless I was asking myself why we did not have these discussions in such depth in my previous teams.

My answer for now is that the teams I worked with until now fell in one of three categories:

A A chief architect, technical lead, etc. made all the design decisions down to the lowest level. His decisions where never questioned as he was considered some kind of genius who was not to be questioned.

B No one really cared about the design. Everyone just did what he thought was best or maybe was the easiest way.

C The team developed a common sense for good and bad design. Smaller design decisions did not need to be discussed as everyone had the same opinion anyway.

As much as I enjoy the discussions in my current team (category D), I think the teams in category C worked much more efficiently.

Still category D is better than A and B.

Obviously B leads to a huge pile of chunk.

A works very efficient too, but if the genius leaves the project (happened to me once) the team is left more or less clueless on how to continue. The team becomes a team of category B or D.

Category D teams should have to potential to evolve to a category C team and therefore become more efficient in creating software designs.

Tuesday, September 30, 2008



Getting Started with Performance Testing in Visual Studio 2008


Analizing the performance of an application is not an easy task. Visual Studio 2008 Team System comes with a set of tools which make it easier to find the bottle necks of a system.



Here is a walk through for the very basic first steps.



I wrote the following program which calculates the Fibonacci number for a given number.

using System;

namespace Fibonacci
{
internal class Program
  {
  private static void Main(string[] args)
    {
    int x = 40;
      Console.WriteLine("Calculating the Fibonacci number for {0}.", x);

      int result = Fibonacci(x);
      Console.WriteLine("The Fibonacci number of {0} is {1}.",
  x,
result);
    }

    private static int Fibonacci(int x)
    {
    if (x < 0)
      {
      throw new ArgumentException("x has to be >= 0", "x");
      }
      if (x == 0)
      {
      return 0;
      }
      if (x == 1)
      {
      return 1;
      }
      return Fibonacci(x - 1) + Fibonacci(x - 2);
    }
  }
}


The calculation takes really long and I want to know where the program spends it time.



So I use the Performance Wizard of Visual Studio to get some performance number for the program.








The wizard lets me choose what to profile. I can choose almost any type of applications and libraries (even existing ones) but in this case I just go with the default selection which is my current program.



Next I have to choose the profiling method, Sampling or Instrumentation. The dialog explains the pros and cons of each method. Sampling is selected by default but I tend to use Instrumentation. For my example I use Instrumentation.


Thats it for this wizard. Just click Finish on the next page and you are ready for profiling.

The next image shows the Performance Explorer which popped up after finishing the performance wizard. For my performance session (Fibonacci) the instrumented targets (binaries) are shown and an empty report.

Next thing to do is launching my program with the profiler to get some performance data.

This first starts up the Visual Studio Performance Monitor (vsperfman.exe) and then my Fibonacci program. As the Fibonacci program is instrumented with performance probes these probes report performance data back to the Performance Monitor.

After the Fibonacci program is finished the Performance Monitor is shut down and a performance report is generated.








Monday, September 22, 2008

Referencing DLLs in Visual Studio 2008


Following problem:

In my project I have to reference the Microsoft.VisualStudio.Profiler.dll, which on my computer is at:

C:Program FilesMicrosoft Visual Studio 9.0Team ToolsPerformance Tools

As some of your developer machines use a German setup, on these machines this DLL is at:

C:ProgrammeMicrosoft Visual Studio 9.0Team ToolsPerformance Tools

So how can I tell Visual Studio to search for the DLL in different directories depending on the machine it is installed?

The solution is easy.

Just add the directory to the "Reference Path" in the projects properties.



The "Reference Path" is stored in "fooproject.csproj.user" so every user can set it differently without interfering with each other.

The downside of this is that every user has to set the "Reference Path".

It would be a better solution to be able to use the %ProgramFiles% system variable in the "Reference Path" and share this setting among all users.


Friday, August 22, 2008

How to Replace Nested foreach Loops With a LINQ Expression

The following nested foreach loops search for all test methods in an assembly:

IEnumerable<String> tests = new List<String>();

Assembly a = Assembly.LoadFrom(dll);
Type[] types = a.GetTypes();

foreach (Type type in types)
{
if (type.IsDefined(typeof (TestClassAttribute), true))
{
MethodInfo[] methods = type.GetMethods();

foreach (MethodInfo method in methods)
{
if (method.IsDefined(typeof (TestMethodAttribute), true))
{
tests.Add(method.Name);
}
}
}
}

return tests;
Using LINQ this function can be rewritten in a very compact yet very readable form:
return from type in Assembly.LoadFrom(dll).GetTypes()
where type.IsDefined(typeof (TestClassAttribute), true)
from method in type.GetMethods()
where method.IsDefined(typeof (TestMethodAttribute), true)
select method.Name;
The first from - where part selects all types which are test classes. The second from where part walks through this list and searches for all methods which are test methods. From these methods the method name is added to the return value.

Note that in LINQ you can combine from - where clauses to generate nested queries.

Tuesday, August 19, 2008

Createing a Bootable DOS USB Stick with OpenSUSE 11.0

Install the FreeDos boot disk with

zypper install dosbootdisk

Create a DOS (type 0x0E) partition on your usb stick with

cfdisk /dev/[usbdevice]

and mark it Boot.

Create the dos boot disk in the partition you created with cfdisk

dosbootdisk [partition on usb stick]

Mount the dos partition and copy whatever additional files (BIOS upgrades, etc.) you need to the stick.

Monday, August 11, 2008

Listing all Test Methods in an Assembly Using C#


In order to write your own test runner you have to find out which methods of your assembly are marked with the attribute TestMethod.

This can be done easily using reflection as the following code example shows.


Assembly a = Assembly.LoadFrom("whatever.dll");
foreach (Type type in a.GetTypes())
{
if (type.IsDefined(typeof (TestClassAttribute), true))
{
MethodInfo[] methods = type.GetMethods();
foreach (MethodInfo method in methods)
{
if (method.IsDefined(typeof (TestMethodAttribute), true))
{
Console.Writeln(method.Name);
}
}
}
}



First we walk through all types of the assembly and search for the attribute TestClassAttribute.
Then we list all methods of the type and search for the attribute TestMethodAttribute.

In this example the result is simply written to the console.


Sunday, June 22, 2008

Installing openSUSE 11.0 on a Dell Vostro 1700

Hardware Specification

CPU

Intel(R) Core(TM)2 Duo T7500 @ 2.20GHz 4MB L2 Cache, 800MHz FSB

Memory

3GB Dual Channel 667MHz DDR2 SDRAM

Chipset

Intel 965PM Express chipset

Graphic Card

NVIDIA GeForce 8600M GT with 256MB DDR2 dedicated graphics memory

Display

17" UltraSharpTM Wide Screen WUXGA (1920x1200) display with TrueLifeTM

Audio

SigmaTel STAC9205

Harddrive

2x Hitachi HTS722016K9A300 160GB 7200 rpm

Optical Drives

TSSTcorp DVD+-RW TSL-623H
DVD+/-RW with Dual Layer DVD

Power

DELL TM9878 battery 7800 mAh

Camera

Omnivision OV2640 2 MPixel 15 fps

Wireless

Dell Wireless Broadcom BCM4310

Mobile Broadband

Not installed

Touchpad

ALPS Electric

Bluetooth

Broadcom BCM2045B2

Network

Broadcom Corporation BCM4401-B0 100Base-TX

Modem

Conexant HDA D330 MDC V.92 Modem

IR

unkown

Card Reader

unkown

ExpressCard

unkown

Installation

Base System

Installed using openSUSE 11.0 DVD. Using the KDE3 Package Using reiserfs for the file systems. Using Raid0 for better disk performance Using proprietary Nvidia drivers

Suspend to Ram

Works out of the box using s2ram -f (as root)

Create /etc/pm/config.d/s2ram:

add S2RAM_OPTS="-f"

su -

echo "S2RAM_OPTS="-f"" > /etc/pm/config.d/s2ram

Suspend to Disk

Not tested so far

External Monitor

Can be configured using nvidia-settings. If the Monitor is not connected on X11 startup KDE3 kicker will extend to the size of both monitors. Workaround: Add the Option "ConnectedMonitors" "DFP, CRT" to the Screen section of /etc/X11/xorg.conf. FN-F8 also works but only works well if Twinview is in Clone mode.

Display DPI

Fixed Display DPI to 96x96 (MS Windows default) Added Option "DPI" "96 x 96" to /etc/X11/xorg.conf Section "Screen"

SVideo Out

Not tested

Multimedia Buttons

Work out of the box. But make sure the main channel in Kmix is set to Front Dimming Buttons work out of the box

Audio

Internal Microphone The internal digital microphones do not work until you manually select a driver in the KDE Arts configuration (ALSA seams to be the best joice) External Microphone add options snd-hda-intel enable=1 index=0 model=dell-m42 to the first line of etc/modprobe.d/sound [http://forums.opensuse.org/hardware/386664-bug-alsa-driver.html] Internal Speakers Works out of the box External Speakers Works out of the box

IEEE 1394

Not tested

Speedstep

Seams to work out of the box

Fans

Seam to work out of the box

Card Reader

Seams to work out of the box

Web-Cam

Works out of the box

Touchpad

Works out of the box

Wireless

Does not work with the bcm43xx or b43 kernel module but with ndiswrapper zypper install ndiswrapper wget ftp://ftp.hp.com/pub/softpaq/sp36501-37000/sp36684.exe mkdir /lib/windrivers mv sp36684.exe /lib/windrivers cd /lib/windrivers cabextract sp36684.exe ndiswrapper -i bcmwl5.inf ndiswrapper -a 14e4:4315 bcmwl5 ndiswrapper -m depmod -a modprobe wlan0 Configure wlan with Yast Add ndiswrapper to MODULES_LOADED_ON_BOOT in /etc/sysconfig/kernel

Bluetooth

Works out of the box

Modem

Not tested

Ir

Not tested

Compiz

Select compiz-kde-launcher in "KDE Control Center -> KDE Components -> Session Manager" create an executeable compiz-kde-launcher script somewhere in your PATH (~/bin) for example put the following content there: #!/bin/bash compiz --replace --sm-disable --ignore-desktop-hints --indirect-rendering --loose-binding ccp & sleep 3 # You can omit this now if you choose emerald --replace & exit 0

Skype

Download openSUSE RPMs from www.skype.com. Install libqt4-32bit, libqt-dbus-1-32bit and libqt4-x11-32bit. Integrated web cam is detected and works out of the box.

ReiserFs

Because of some bug in ReiserFs the system sometimes freezes. Changing the options of ReiserFs file systems in /etc/fstab to noatime,noacl may remove the problem also not confirmed yet.

Remove Projects from the Recent Project List in Visual Studio 2005


The list is stored in the registry at:

HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio8.0ProjectMRUList

Just remove the entries you do not want to be shown in the recent project list.





Friday, May 9, 2008

OpenSUSE Sync Treo 650 With KDE Kontakt Using KPilot

Using Bluetooth:

Based on: http://www.newt.com/debian/treo650.html

Enable DUND and set DUND Options to
--listen --persist --msdun call treo
in YAST -> Hardware -> Bluetooth


In /etc/ppp/peers/ create a script called treo with the following contents

115200
192.168.33.2.1:192.168.33.2
local
ms-dns 127.0.0.1
noauth
debug

Set the device in KPilot to net:any

[Update]

For whatever reason this does not work on my new laptop.

But starting dund manulally with
dund --listen --persist --msdun call treo
works.

I cant see the difference between this and the startup via /etc/init.d/bluetooth but nevertheless I have a workaround.




Installing openSUSE 10.3 on a Dell Vostro 1700

Installing openSUSE 10.3 on a Dell Vostro 1700

Hardware Specification

CPU

Intel(R) Core(TM)2 Duo T7500 @ 2.20GHz 4MB L2 Cache, 800MHz FSB

Memory

3GB Dual Channel 667MHz DDR2 SDRAM

Chipset

Intel 965PM Express chipset

Graphic Card

NVIDIA GeForce 8600M GT with 256MB DDR2 dedicated graphics memory

Display

17" UltraSharpTM Wide Screen WUXGA (1920x1200) display with TrueLifeTM

Audio

SigmaTel STAC9205

Harddrive

2x Hitachi HTS722016K9A300 160GB 7200 rpm

Optical Drives

TSSTcorp DVD+-RW TSL-623H
DVD+/-RW with Dual Layer DVD

Power

DELL TM9878 battery 7800 mAh

Camera

Omnivision OV2640 2 MPixel 15 fps

Wireless

Dell Wireless Broadcom BCM4310

Mobile Broadband

Not installed

Touchpad

ALPS Electric

Bluetooth

Broadcom BCM2045B2

Network

Broadcom Corporation BCM4401-B0 100Base-TX

Modem

Conexant HDA D330 MDC V.92 Modem

IR

unkown

Card Reader

unkown

ExpressCard

unkown

Installation

Base System

Installed using openSUSE 10.3 DVD. Using the KDE3 Package Using reiserfs for the file systems. Using proprietory Nvidia drivers

Suspend to Ram

Works out of the box using s2ram -f (as root)

Create /etc/pm/config.d/s2ram:

add S2RAM_OPTS="-f"

Suspend to Disk

Not tested so far

External Monitor

Can be configured using nvidia-settings. If the Monitor is not connected on X11 startup KDE3 kicker will extend to the size of both monitors. [SOLVED] Add the Option "ConnectedMonitors" "DFP, CRT" to the Screen section of /etc/X11/xorg.conf. FN-F8 also works but only works well if Twinview is in Clone mode.

Display DPI

Fixed Display DPI to 96x96 (MS Windows default) Added Option "DPI" "96 x 96" to /etc/X11/xorg.conf Section "Screen"

SVideo Out

Not tested

Multimedia Buttons

Work out of the box. But make sure the main channel in Kmix is set to Front

Audio

Internal Microphone The internal digital microphones do not work until you manually select a driver in the KDE Arts configuration (ALSA seams to be the best joice) External Microphone Does not work Internal Speakers Works out of the box External Speakers Works out of the box

IEEE 1394

Not tested

Speedstep

Seams to work out of the box

Fans

Seam to work out of the box

Card Reader

Seams to work out of the box

Web-Cam

Works out of the box

Touchpad

Works, but without scrolling. Tapping (left mouse click) works. Seams not to be detected by the kernel as touch pad just as a normal mouse. [SOLVED] This is because the Alps Touchpad is not detected by the kernel. This can be fixed by trivial patch to the alps module. Install the kernel-source package. Edit the file: /usr/src/linux/drivers/input/mouse/alps.c In line 56 add { { 0x73, 0x02, 0x50 }, 0x4f, 0x4f, ALPS_FW_BK_1 }, as root: cd /usr/src/linux make cloneconfig make make install_modules make install reboot Now the touch pad should show up in /proc/bus/input/devices as I: Bus=0011 Vendor=0002 Product=0008 Version=7325 N: Name="AlpsPS/2 ALPS GlidePoint" P: Phys=isa0060/serio1/input0 S: Sysfs=/class/input/input3 U: Uniq= H: Handlers=mouse1 event3 B: EV=f B: KEY=420 670000 0 0 0 0 B: REL=3 B: ABS=1000003 You may use sax to configure it for your x11

Wireless

Does not work with the bcm43xx kernel module but with ndiswrapper Download driver from ftp://ftp.hp.com/pub/softpaq/sp36501-37000/sp36684.exe mkdir /lib/windrivers mv sp36684.exe /lib/windrivers cd /lib/windrivers cabextract sp36684.exe ndiswrapper -i bcmwl5.inf ndiswrapper -a 14e4:4315 bmwl5 ndiswrapper -m depmod -a modprobe wlan0 Configure wlan with Yast Add ndiswrapper to MODULES_LOADED_ON_BOOT in /etc/sysconfig/kernel

Bluetooth

Works out of the box

Modem

Not tested

Ir

Not tested

Compiz

Installed Compiz Fusion Icon. Worked out of the box. Made it loading on KDE startup with ln -s /usr/share/applications/fusion-icon.desktop ~/.kde/Autostart

Skype

Download openSUSE RPMs from www.skype.com. Install libqt4-32bit, libqt-dbus-1-32bit and libqt4-x11-32bit. Integrated web cam is detected and works out of the box.

Friday, April 11, 2008

Implementing your own little delegates for Java

Not having delegates in Java makes writing Eventhandlers etc. a pain from the syntax perspective. Nevertheless you can achieve something like a delegate with Java's reflection mechanisms.

Here is the problem I was working on:

I had a Manager class which managed a list of clients. The Manger class consisted mainly out of methods calling a method with the same name for each client and returning the first valid return value of the client.

class Manager {
List<Client> clients;

public String a(String param) {
for(Client client : clients) {
String retval = client.a(param)
if (retval != null) {
return retval
}
}
}
public String b(String param) {
for(Client client : clients) {
String retval = client.b(param)
if (retval != null) {
return retval
}
}
}
public String c(String param) {
for(Client client : clients) {
String retval = client.c(param)
if (retval != null) {
return retval
}
}
}

}



Well using some kind of Command pattern this could be solved a lot better, but the syntax would not be very readable.

I would be better to write something like:

class Manager {
List<Client> clients;

public String a(String param) {
return eachClient( a, param) );
}
public String b(String param) {
return eachClient( b, param) );
}
public String c(String param) {
return eachClient( c, param) );
}
}


The good news is in Java you can build this syntax (if you are willing to pay the performance price of reflection)

Here is how this works:

First create a eachClient method passing in the method name and the original parameters as parameters. Search for the method in the Client class. For each client execute the method.

Easy it sounds easy it is. Here is the eachClient method:

Object eachClient(String method, Object... params) {
for(Client client : clients) {
Method m = getMethod(client, method, params);
Object o = m.invoce(client, params);
if (o != null) {
return o
}
}
}


The getMethod method look like this:

Method getMethod(Object target, String methodName, Object... params)
throws SecurityException, NoSuchMethodException {
Class[] parameterTypes = new Class[params.length];

for (int i = 0; i < params.length; i++) {
parameterTypes[i] = params[i].getClass();
}
return target.getClass().getMethod(methodName, parameterTypes);
}
}


Note that the exception handling in eachClient is not mentioned here to make the examples more readable.

Note that getMethod will not find methods if the parameter objects class is an inherited class of the parameter class specified in the method signature.

Saturday, April 5, 2008

Converting boolean array to int in Java

In a X509Certificate the key usage is stored as a boolean array. In order to be able to use the bitwise and & on this boolean[] it has to be converted into an int. This is how you can do this:

  int booleanArrayToInt(boolean[] a)
  {
    int result = 0;
    for (int i = 0; i < a.length; i++)
    {
      int value = (a[i] ? 1 : 0) << i;
      result = result | value;
    }

    return result;
  }

Groovy Beginner Tutorials

For a lecture I put together a presentation showing how to install the Groovy Eclipse plugin and created a video showing how to implement a basic "Hello world" application in Groovy.

The presentation is available here: Installation of the Groovy Eclipse plugin

The video is available here: Groovy Hello World tutorial

Friday, March 28, 2008

Uploading Images to Flickr using flickcurl and Groovy

For the latest Groosh release I created an more elaborate example of how to use Groovy and Groosh. This example shows how to upload Images to a Flickr account using Groovy, Groosh and flickcurl.

import static groosh.Groosh.groosh
import static org.codehaus.groovy.groosh.stream.DevNull.devnull

ids = [:]
shell = groosh()

//get all images in this folder and upload it to flickr
//remember the photo id we get from flickr
shell.ls().grep(~/.*jpg/).each {
println "Uploading file $it to flickr"
flickcurl = shell.flickcurl("upload",it,"friend","family")
.useError(true)
id = flickcurl.grep(~/.*Photo ID.*/)[0].split(":")[1].trim()
ids[it] = id
println "Photo ID is: $id"
}
//we need to know the first photo id
firstKey = ids.keySet().toList()[0]

//create a set with the name of the directory we are in right now
//use the id of the first photo as set cover
setName = shell.pwd().text.split("/")[-1]
println "Creating set: $setName"
flickcurl = shell.flickcurl("photosets.create",setName,setName,ids[firstKey])
.useError(true)
id = flickcurl.grep(~/.*Photoset.*/)[0].split(" ")[2].trim()
println "Photoset ID is: $id"

//make a backup of the ids in a file for later reference
println "Writing ids to a file"
file = new File(shell.pwd().text.trim() + "/.flickrset")
file << "Photoset:" << id << "\n"
ids.each {
file << it.key << ":" << it.value << "\n"
}

//the first photo is allready part of the photo set so lets remove it
ids.remove(firstKey)

//add the remaining photos to the photo set
ids.each {
println "Adding photo to set at flickr: $it"
shell.flickcurl("photosets.addPhoto",id,it.value) | devnull()
}

println "DONE"

Groosh 0.3.0 released

Version 0.3.0 of Groosh released

Groosh (http://groovy.codehaus.org/Groosh) provides shell-like capability for handling external processes for Groovy.

Version 0.3.0 comes with several bug fixes and new features like:

  • The error stream of a process is now usable the same way as the output stream (useError()).
  • A grep method was added which can be used to filter the lines returned by a process.
  • A to List method was added which creates a list out of the lines returned by a process.
  • A eachLine method was added which iterates over the lines returned by a process.
  • The exit values of a process are now accessible. (Thx to Bill Burdick)
  • left shift and right shift operators are overloaded for processes and stream sinks.
  • the pipe operator was overloaded to allow chaining of processes

For more information on Groosh and examples of its use see:
http://groovy.codehaus.org/Groosh

Groosh 0.3.0 can be downloaded from

http://svn.codehaus.org/groovy-contrib/groosh/releases/

OpenSUSE RPM packages are available from

http://download.opensuse.org/repositories/home:/eggeral/openSUSE_10.3/
and
http://download.opensuse.org/repositories/home:/eggeral/openSUSE_10.2/

Friday, March 21, 2008

Setting up openSuse build service for the generation of javac dependent packages

I have my own little openSuse build service account for the generation of same Java related packages. Mainly Groovy stuff.

If you want to use javac in the build process you need to add the build requirement to java-devel. Unfortunately this package is not available in the openSUSE_10.2 and openSUSE_10.3 standard repositories. They are available in the openSUSE_10.2:NonFree and openSUSE_10.2:NonFree repositories, but there is no option in the web interface of the build service which allows to configure this.

You have to use the build service API do change this configuration. Which is in fact very easy because the API is a REST like service which can be used for example with kwrite.

So

kwrite https://api.opensuse.org/source/home:eggeral/_meta

allows you do edit the configuration of the repositories. Just add

<path project="openSUSE:10.3:NonFree" repository="standard">

and you have access to the Sun Java rpms.

See

http://news.opensuse.org/2007/07/18/nice-trick-to-use-apiopensuseorg-native-with-kde-apps/

for more information on the openSuse build service API.