Month: June 2014

Optimize java startup speed

I spent lot of time to optimize the startup speed of my Java app from 10 seconds down to 6 seconds in my 2012 Mac air. I changed to MacBook 13″, the startup time become <=3. That proves the hard disk speed is the key to optimize the startup time.

I am facing a new problem in Retina display: When I resize the window, the screen update is a little bit slow.

read count : 328

How to use PFSBuilder

How to use PFSBuilder

This tutorial work in windows/linux/mac

Step 1) Download the jar

Step 2) make sure you have java in your PC

Compress directory into PFS image

Step 1) Make sure PFSBuilder.jar is in your current directory

Step 2) Create a folder call “input” and put some files and directories in there

PFSBuilder 1

Step 3) PFSBuilder has two modes: GUI mode and command line mode. Type this command to compress the “input” folder into a PFS file image called “harddisk”.

java -jar PFSBuilder-20140619.jar -c -inputdirectory input -output harddisk -partitionsize 10MB -partitionname tutorial -blocksize 2048 -projectfile project.ini

If the command is success, file “harddisk” will be created, see below

PFSBuilder 2

Compress directory into PFS image using GUI mode

Step 1) start PFSbuilder by -gui option

java -jar PFSBuilder-20140619.jar -gui

Step 2) Follow the below steps

Click the “New button”
PFSBuilder 3



Type in details and click “New”

PFSBuilder 4

Right click the tree and click “Import Directory”, select a folder you want to compress

PFSBuilder 5

If it is success to import the directory, you see something like below image

PFSBuilder 6

Click on any file on LHS, file content will be displayed on RHS

PFSBuilder 7

Finally, click “Save” button, the PFS file image will be created

PFSBuilder 8


Decompress PFS file image into a folder

java -jar PFSBuilder-20140619.jar -input harddisk -outputdirectory output -x -partitionoffset 0 -projectfile project.ini

It will extract all folders and files in PFS image “harddisk” to directory called “output”

Command line options

PFSBuilder command line options

read count : 344

Connect Peter-file-system to linux or mac

After spent 3 days to play the FUSE and macFUSE, i finally connected Peter-file-system ( to my mac/linux machine.

Connect PFS to real FS
Connect PFS to real FS

It is quite simple and straightforward, I write a FUSE program that create a JVM and load my PFS stub (writhed in Java), every FUSE function calls will route to the stub and manipulates the PFS image. Here is the diagram:

How FUSE and PFS work
How FUSE and PFS work

The PFSBuilder can do these things:
1) compress/decompress a PFS image file from a directory
2) FUSE stub

PFS fs spec is here . I made PFS in 2005, it is a very simple FS and doesn’t have much feature. I made it because I want to know how the FS work and I did insert PFS to my hobby kernel

My hobby kernel
My hobby kernel

Don’t ask me what are the advantages of PFS, the only one advantage it has is : it has no advantage.

read count : 525

code crash in multithread mode of FUSE

 FUSE: Filesystem in Userspace
 Copyright (C) 2001-2007  Miklos Szeredi <>

 This program can be distributed under the terms of the GNU GPL.
 See the file COPYING.

 gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello


#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <jni.h>
#include <pthread.h>

static const char *peter_str = "Hello World!\n";
static const char *peter_path = "/hello";
pthread_mutex_t mutex1;
static jclass cls;
jmethodID readdir;
static JNIEnv *env;
static JavaVM *jvm;

void create_vm() {
	//JNIEnv *env;
	JavaVMInitArgs vm_args;
	JavaVMOption options;
	options.optionString =
	vm_args.version = JNI_VERSION_1_6;
	vm_args.nOptions = 1;
	vm_args.options = &options;
	vm_args.ignoreUnrecognized = 0;

	JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args);
	return env;

static int peter_getattr(const char *path, struct stat *stbuf) {
	printf("--------------- peter_getattr = %s\n", path);
	int res = 0;

	memset(stbuf, 0, sizeof(struct stat));
	if (strcmp(path, "/") == 0) {
		printf("--------------- root /\n");
		stbuf->st_mode = S_IFDIR | 0755;
		stbuf->st_nlink = 2;
	} else if (strcmp(path, peter_path) == 0) {
		stbuf->st_mode = S_IFREG | 0444;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(peter_str);
	} else
		res = -ENOENT;

	return res;

static int peter_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
		off_t offset, struct fuse_file_info *fi) {
	printf("--------------- peter_readdir = %s\n", path);
	(void) offset;
	(void) fi;

	if (strcmp(path, "/") != 0)
		return -ENOENT;

	filler(buf, ".", NULL, 0);
	filler(buf, "..", NULL, 0);
	filler(buf, peter_path + 1, NULL, 0);

	jstring paraReadDir = (*env)->NewStringUTF(env, "Peter cheung");
	(*env)->CallStaticVoidMethod(env, cls, readdir, paraReadDir);
	return 0;

static int peter_open(const char *path, struct fuse_file_info *fi) {
	printf("--------------- peter_open = %s\n", path);
	if (strcmp(path, peter_path) != 0)
		return -ENOENT;

	if ((fi->flags & 3) != O_RDONLY)
		return -EACCES;

	return 0;

static int peter_read(const char *path, char *buf, size_t size, off_t offset,
		struct fuse_file_info *fi) {
	printf("--------------- peter_read = %s\n", path);
	size_t len;
	(void) fi;
	if (strcmp(path, peter_path) != 0)
		return -ENOENT;

	len = strlen(peter_str);
	if (offset < len) {
		if (offset + size > len)
			size = len - offset;
		memcpy(buf, peter_str + offset, size);
	} else
		size = 0;

	return size;

static struct fuse_operations peter_oper = { .getattr = peter_getattr,
		.readdir = peter_readdir, .open = peter_open, .read = peter_read, };

int main(int argc, char *argv[]) {
	cls = (*env)->FindClass(env, "com/pfsbuilder/fuse/FuseStub");

	if (cls == 0) {
		printf("load class error\n");
	readdir = (*env)->GetStaticMethodID(env, cls, "readdir",
	if (readdir == 0) {
		printf("load readdir error\n");
	jstring paraReadDir = (*env)->NewStringUTF(env, "Peter cheung");
	(*env)->CallStaticVoidMethod(env, cls, readdir, paraReadDir);

	pthread_mutex_init(&mutex1, NULL);
	return fuse_main(argc, argv, &peter_oper, NULL);

read count : 333

How to trace IIS error 500

The best way to trace IIS error 500 is to enable all log detail on screen, edit your web.config to

        <httpErrors errorMode="Detailed" />
        <asp scriptErrorSentToBrowser="true"/>
        <customErrors mode="Off"/>
        <compilation debug="true"/>

read count : 243

How titan connect to kvm’s vnc through titan server via java object stream

I nearly don’t understand the code I wrote 6 months ago about the vnc connection. It is a little complex, the basic idea is : Titan server create a proxy server to the kvm’s vnc. Titan server is using java object stream to communicate with client, it wrap all the bytes from the object stream to kvm’s vnc server through the proxy server that created by the “proxy” command.

titan proxy server to vnc
titan proxy server to vnc

read count : 375

Titan portal

Developing the titan portal, which is for hosting company’s customers. If you want to build a hosting company using openstack, you definitely need a portal for your customer to provide operations.

Titan portal
Titan portal
Titan portal 2
Titan portal 2

read count : 297