Archive for January, 2009

VirtualBox does not send Control key events to guest OS.

Friday, January 23rd, 2009
Now that's a strange one.

This is the case: you run Windows XP as a guest operating system in VirtualBox in your Ubuntu box. However, VirtualBox refuses to send events for the Control key (for example, if you press Ctrl-N Windows XP will just receive 'N').

It is possible that the problem is caused by a feature of Ubuntu rather than a bug in VirtualBox. Specifically you have to make sure that you have unchecked the Show position of pointer when the Control key is pressed.

Go to System → Preferences → Mouse → General. Make it look like this:

locate-pointer.jpg



Showing the position of the pointer is neat feature but it seems that you have to live without it if you want Control key events to be passed in your VirtualBox guests...

Creating Symbolic Links with Java at Runtime

Sunday, January 4th, 2009
For the time being it seems that there is no other way than calling an external program for doing the job:

Process process = Runtime.getRuntime().exec( new String[] { "ln", "-s", oldName, newname } );
process.waitFor();
process.destroy();


The disadvantage of this method is the overhead for creating the new process. This can be a serious downgrade in performance if you have to execute this code frequently.

Here is an alternative solution that can vastly improve speed.

First you write a small program in C, say it symlinkcreator.c. This is the actual worker:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int main()
{
char st[1024];
char oldpath[1024];
int count = 0;

while (fgets(st,sizeof(st),stdin) != NULL)
{
for (char *cp = st; *cp; cp++)
if (*cp == '\n' || *cp == '\r') *cp = '\0';

if (count++ % 2)
symlink(oldpath,st);
else
strcpy(oldpath,st);
}
}


You can compile the program by running this command:

# gcc symlinkcreator.c -o symlinkcreator -std=c99

This will give you the symlinkcreator executable file.

Then you going to need an elegant wrapper class that will call the C program:

import java.io.IOException;
import java.io.PrintWriter;

public class SymlinkCreator
{
private Process process;
private PrintWriter out;

public SymlinkCreator( String path ) throws IOException
{
process = Runtime.getRuntime().exec(path);
out = new PrintWriter(process.getOutputStream());
}

public void link( String oldpath, String newpath )
{
out.println(oldpath);
out.println(newpath);
out.flush();
}

public void terminate() throws InterruptedException
{
out.close();
process.waitFor();
process.destroy();
}
}


Have done these, you can then easily create symbolic links from you code, like this:

// You only need one single SymlinkCreator object (just a single unix process is created)
SymlinkCreator symlinkCreator = new SymlinkCreator("/path/to/symlinkcreator");
...
// Create as many symbolic links as you want using the same process
symlinkCreator.link(oldName,newName);
...
// Terminate the symbolic creator process and release resources when done.
symlinkCreator.terminate();


Downloads:
symlinkcreator.c

SymlinkCreator.java




Alternatively, you can use native methods to eliminate the hassle of inter-process communication between two separate processes.

First create a Symlink class that defines the signatures of the native mathod. This class will act as an interface to the actual C functions:

public class Symlink
{
public native static void create( String oldpath, String newpath );
}


Then you will need to generate a header file for this class using the javah utility:

# javah -classpath /path/to/your/classes Symlink

This will generate a header file that looks like this:

Symlink.h

#include <jni.h>
/* Header for class Symlink */

#ifndef _Included_Symlink
#define _Included_Symlink
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     Symlink
* Method:    create
* Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Symlink_create
(JNIEnv *, jclass, jstring, jstring);

#ifdef __cplusplus
}
#endif
#endif


Then you will have to write a small C file that will define the implemtation of the  function:

Symlink.c

#include <unistd.h>

#include <jni.h>

#include "Symlink.h"

JNIEXPORT void JNICALL Java_Symlink_create
(JNIEnv *env, jclass obj, jstring oldpath, jstring newpath)
{
const char *nativeOldpath = (*env)→GetStringUTFChars(env, oldpath, 0);
const char *nativeNewpath = (*env)→GetStringUTFChars(env, newpath, 0);

symlink(nativeOldpath,nativeNewpath);

(*env)→ReleaseStringUTFChars(env, oldpath, nativeOldpath);
(*env)→ReleaseStringUTFChars(env, newpath, nativeNewpath);
}


Then you have to compile the C file as a shared library:

# gcc -shared -o Symlink.so Symlink.c -I /path/to/jdk/include -I /path/to/jdk/include/linux

You will have to load this shared library at the runtime of your java program.

Finally you can write a small test program to see that everything works:

public class TestSymlink
{
public static void main( String[] args )
{
System.load("/path/to/Symlink.so");
Symlink.create("/home/giannis/test1", "/home/giannis/test2");
}
}


zenity windows and dialogs "hidden"

Saturday, January 3rd, 2009
I just discovered that zenity dialogs show up underneath all the other open windows. It was a matter of five seconds to google it and find out that this is a bug of zenity that causes this symptom if zenity is used in combination with Compiz or Metacity.

You can easily fix this problem by applying a small patch. Just run these two commands:

# wget http://launchpadlibrarian.net/18653141/zenity-2.24.0-focus.patch
# sudo patch -p0 /usr/share/zenity/zenity.glade < zenity-2.24.0-focus.patch


The original information was found in launchpad.