Sunday, 14 April 2013

Aurinko2: A scala document database engine

Are you looking for an XML document database engine?

Recently I have been working on a spare-time project called Aurinko2, which is an XML document database engine implementation in Scala.

Check it out if you wish: Aurinko2

Main Features:
  • Store, manage and retrieve XML documents
  • Client-server data exchange using XML format
  • Build powerful queries using built-in simple query syntax
  • Optimised for scalability on SMP systems with fairness guarantee
  • Never lose your data in case of a crash
Please leave your feedback/suggestions, thank you!

Sunday, 10 March 2013

How to set SBT JVM parameters (and change heap size)

(This article applies to SBT 0.12.0)

SBT offers 3 ways to pass JVM parameters:
  • Set environment variable SBT_OPTS
  • Set environment variable JAVA_OPTS
  • Pass parameters by command line option `-J-X`
They all work for any JVM parameter other than heap size settings.

How to change SBT JVM heap size settings

If you use any of the above 3 ways to to set JVM heap size, you will notice that SBT's JVM does not use your new heap size settings at all.

Later on I figured out the reason: your JVM heap size settings are simply overridden by SBT (feature or bug?)

It is easy to remove the override, change /usr/share/sbt/sbt-launch-lib.bash

And get rid of the - line:
  # run sbt
  execRunner "$java_cmd" \
    ${SBT_OPTS:-$default_sbt_opts} \
-   $(get_mem_opts $sbt_mem) \
    ${java_opts} \
    ${java_args[@]} \
    -jar "$sbt_jar" \
    "${sbt_commands[@]}" \
    "${residual_args[@]}"
And afterwards, you may use anyway you like to set JVM heap size settings.

Tuesday, 5 March 2013

How to Execute SQL Script file using Java JDBC

How to execute SQL script file using Java JDBC connection?

You have two ways:
  • Break up SQL script into statements and execute it statement by statement.
  • Pass the script file to database engine CLI.
If the first way is more suitable for you, here is a piece of Java code ready for you to use. It has the following features:
  1. Support SQL comment lines (prefixed by "--", "//" or "#")
  2. Support changing of delimiters
  3. Break up SQL script and run it statement by statement
  4. Print out query results
  5. Print out number of updates
My version is heavily modified from ScriptRunner 's implementation modified by a StackOverflow user. The changes are:
  • Code clean-up
  • Better SQL comment support
  • Fix query result output index-out-of-range issue
Additional readings: http://stackoverflow.com/questions/1497569/how-to-execute-sql-script-file-using-jdbc

Here is my source code:

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

public class SqlRunner {
    public static final String DELIMITER_LINE_REGEX = "(?i)DELIMITER.+", DELIMITER_LINE_SPLIT_REGEX = "(?i)DELIMITER", DEFAULT_DELIMITER = ";";
    private final boolean autoCommit, stopOnError;
    private final Connection connection;
    private String delimiter = SqlRunner.DEFAULT_DELIMITER;
    private final PrintWriter out, err;

    public SqlRunner(final Connection connection, final PrintWriter out, final PrintWriter err, final boolean autoCommit, final boolean stopOnError) {
        if (connection == null) {
            throw new RuntimeException("SqlRunner requires an SQL Connection");
        }
        if (err == null || out == null) {
            throw new RuntimeException("SqlRunner requires both out and err PrintWriters");
        }
        this.connection = connection;
        this.autoCommit = autoCommit;
        this.stopOnError = stopOnError;
        this.out = out;
        this.err = err;
    }

    public void runScript(final Reader reader) throws SQLException {
        final boolean originalAutoCommit = this.connection.getAutoCommit();
        try {
            if (originalAutoCommit != this.autoCommit) {
                this.connection.setAutoCommit(this.autoCommit);
            }
            this.runScript(this.connection, reader);
        } finally {
            this.connection.setAutoCommit(originalAutoCommit);
        }
    }

    private void runScript(final Connection conn, final Reader reader) {
        StringBuffer command = null;
        try {
            final LineNumberReader lineReader = new LineNumberReader(reader);
            String line = null;
            while ((line = lineReader.readLine()) != null) {
                if (command == null) {
                    command = new StringBuffer();
                }
                String trimmedLine = line.trim();

                if (trimmedLine.startsWith("--") || trimmedLine.startsWith("//") || trimmedLine.startsWith("#")) {

                    // Line is a comment
                    out.println(trimmedLine);
                    out.flush();

                } else if (trimmedLine.endsWith(this.delimiter)) {

                    // Line is end of statement

                    // Support new delimiter
                    final Pattern pattern = Pattern.compile(SqlRunner.DELIMITER_LINE_REGEX);
                    final Matcher matcher = pattern.matcher(trimmedLine);
                    if (matcher.matches()) {
                        delimiter = trimmedLine.split(SqlRunner.DELIMITER_LINE_SPLIT_REGEX)[1].trim();

                        // New delimiter is processed, continue on next
                        // statement
                        line = lineReader.readLine();
                        if (line == null) {
                            break;
                        }
                        trimmedLine = line.trim();
                    }

                    // Append
                    command.append(line.substring(0, line.lastIndexOf(this.delimiter)));
                    command.append(" ");

                    Statement stmt = null;
                    ResultSet rs = null;
                    try {
                        stmt = conn.createStatement();
                        out.println();
                        out.println(command);
                        out.flush();
                        boolean hasResults = false;
                        if (this.stopOnError) {
                            hasResults = stmt.execute(command.toString());
                        } else {
                            try {
                                stmt.execute(command.toString());
                            } catch (final SQLException e) {
                                e.fillInStackTrace();
                                err.println("Error on command: " + command);
                                err.println(e);
                                err.flush();
                            }
                        }
                        if (this.autoCommit && !conn.getAutoCommit()) {
                            conn.commit();
                        }
                        rs = stmt.getResultSet();
                        if (hasResults && rs != null) {

                            // Print result column names
                            final ResultSetMetaData md = rs.getMetaData();
                            final int cols = md.getColumnCount();
                            for (int i = 0; i < cols; i++) {
                                final String name = md.getColumnLabel(i + 1);
                                out.print(name + "\t");
                            }
                            out.println("");
                            out.println(StringUtils.repeat("---------", md.getColumnCount()));
                            out.flush();

                            // Print result rows
                            while (rs.next()) {
                                for (int i = 1; i <= cols; i++) {
                                    final String value = rs.getString(i);
                                    out.print(value + "\t");
                                }
                                out.println("");
                            }
                            out.flush();
                        } else {
                            out.println("Updated: " + stmt.getUpdateCount());
                            out.flush();
                        }
                        command = null;
                    } finally {
                        if (rs != null)
                            try {
                                rs.close();
                            } catch (final Exception e) {
                                err.println("Failed to close result: " + e.getMessage());
                                err.flush();
                            }
                        if (stmt != null)
                            try {
                                stmt.close();
                            } catch (final Exception e) {
                                err.println("Failed to close statement: " + e.getMessage());
                                err.flush();
                            }
                    }
                } else {

                    // Line is middle of a statement

                    // Support new delimiter
                    final Pattern pattern = Pattern.compile(SqlRunner.DELIMITER_LINE_REGEX);
                    final Matcher matcher = pattern.matcher(trimmedLine);
                    if (matcher.matches()) {
                        delimiter = trimmedLine.split(SqlRunner.DELIMITER_LINE_SPLIT_REGEX)[1].trim();
                        line = lineReader.readLine();
                        if (line == null) {
                            break;
                        }
                        trimmedLine = line.trim();
                    }
                    command.append(line);
                    command.append(" ");
                }
            }
            if (!this.autoCommit) {
                conn.commit();
            }
        } catch (final SQLException e) {
            e.fillInStackTrace();
            err.println("Error on command: " + command);
            err.println(e);
            err.flush();
        } catch (final IOException e) {
            e.fillInStackTrace();
            err.println("Error on command: " + command);
            err.println(e);
            err.flush();
        }
    }
}

Monday, 4 March 2013

Useful Linux aliases

Shell aliases really come in handy when we use shell frequently, here is a list of my shell aliases which I use everyday:



# go to parent directory
alias '..'='cd ..;'
# go to parent's parent directory
alias '...'='cd ../..;'
# search by regex or anything, with coloring and line numbering
alias grep='egrep --color=auto -n'
# list files with coloring, list their type, human readable file size and sorted by modified time (latest at bottom)
alias l='ls -AFhltr --color=auto'
# Fix for 'sudo does not recognize alias'
alias sudo='sudo '

Javascript fix to Internet Explorer dropdown list width problem

Internet Explorer is probably the only web browser in the world which does not automatically expand dropdown list's width to fit its content. This are many fixes around (mainly using JS and CSS), however in real scenarios I found the existing fixes not working sometimes. So here I write my own, it uses JQuery:

$(document).ready(function() {
  if ($.browser.msie) {
    $('body').mouseenter(function() {
      $('select').each(function() {
      if ($(this).data('msie_dropdown_fix_open') == false) {
        $(this).mouseleave();
      }
    });
  });
  $('select').each(function() {
    $(this).data('msie_dropdown_fix_width', $(this).width());
    $(this).data('msie_dropdown_fix_open', false);
  });
  $('select').mouseenter(function() {
    if (!$(this).hasClass("nowidthfix")) {
      $(this).css('width', 'auto');
    }
    // never shorten width of drop down list
    if ($(this).width() < $(this).data('msie_dropdown_fix_width')) {
      $(this).css('width', $(this).data('msie_dropdown_fix_width'));
    }
  });


  $('select').click(function() {
    $(this).data('msie_dropdown_fix_open', true);
  });
  $('select').mouseleave(function() {
    if ($(this).data('msie_dropdown_fix_open') == false && $(this).data('msie_dropdown_fix_width') > 10) {
      $(this).css('width', $(this).data('msie_dropdown_fix_width'));
    }
  });
  $('select').blur(function() {
    $(this).data('msie_dropdown_fix_open', false);
  });
  $('select').change(function() {
    $(this).data('msie_dropdown_fix_open', false);
  });
 }
});


The above script makes all drop down lists become wider when user mouse over them, and restore to their original width when mouse leaves them.


$.browser.msie has been removed since JQuery V1.9. You may want to use other ways to detect if user is using IE browser. Here is one way: http://pupunzi.open-lab.com/2013/01/16/jquery-1-9-is-out-and-browser-has-been-removed-a-fast-workaround/
Or simply:
/msie/.test(navigator.userAgent.toLowerCase())

How to solve PPTP VPN client cannot open web pages

If you are running PPTP VPN server (pptpd) on a Linux host, and your PPTP clients cannot open any web pages, here is a checklist for you to debug the problem:

  1. Is there another client connected to the PPTP VPN server?
    If two clients are under the same NAT, they may not connect to the same PPTP VPN server at once. This is a limitation in PPTP implementation.
  2. Does PPTP VPN server allow IP forwarding?Check kernel configuration on the PPTP server and make sure that ip_forward is enabled by running:
    # sysctl -a | grep ip_forward
    If you see net.ipv4.ip_forward = 0
    That means IP forwarding is not enabled and you must enable it. One way is to edit /etc/sysctl.conf and change/add the following line:
    net.ipv4.ip_forward = 1
  3. Does PPTP VPN server firewall masquerade network interfaces?
    It is essential to configure firewall to masquerade public Internet network interface and ppp network interface, here are the firewall rules:
    iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
    iptables -A POSTROUTING -t nat -o ppp+ -j MASQUERADE

  4. Does PPTP VPN server have clamp-mss-to-pmtu set in iptables?If your VPN clients can visit certain websites but not others, then you are very likely encountering MTU problem. It can be fixed easily by the following iptables rule:
    iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
  5. Are DNS server addresses set correctly on PPTPD configuration?If your VPN clients can ping IP addresses (such as Google DNS 8.8.8.8) but not visiting any websites, then it is likely a DNS issue. You can set DNS server addresses on VPN clients, or set them on the VPN server's options.pptpd, change/add the following lines:
    ms-dns 8.8.8.8
    ms-dns 8.8.4.4

Create a VPN server for Blackberry Playbook (or Blackberry 10) using StrongSwan

Background

In this tutorial, we will talk about creating a generic L2TP/IPSEC server for Blackberry Playbook on a Linux host running StrongSwan.

There are some other tutorials on this topic, however those tutorials are not entirely accurate, IPSec is a very complicated protocol and very difficult to setup - there are many things to be take care of before getting you this VPN connection.

We will use StrongSwan to host a generic L2TP/IPSec server using IKEv2 key exchange protocol.

Some tutorials suggest that StrongSwan does not support IKE aggressive key exchange mode and thus not suitable for being Playbook's VPN server - this statement is very inaccurate. Playbook will connect to a StrongSwan server without support of IKE aggressive key exchange.

My hosting environment is an Amazon EC2 free micro server running CentOS 6.3.

Software

StrongSwan is a popular IPSec implementation. I am using StrongSwan 5.0.4 compiled from source code downloaded from the official StrongSwan website.

By default, StrongSwan compilation does NOT include IKEv2 support. You MUST configure it (./configure <options>) to enable the following plugins:
charon curl ldap pkcs11 aes des sha1 sha2 md4 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs8 pgp dnskey pem openssl fips-prf gmp xcbc cmac hmac ccm gcm attr kernel-netlink resolve socket-default farp stroke updown eap-identity eap-aka eap-aka-3gpp2 eap-md5 eap-gtc eap-mschapv2 eap-dynamic eap-radius eap-tls eap-ttls eap-peap eap-tnc xauth-generic xauth-eap dhcp

OS configuration

Firewall

Enable masquerade (replace eth0 by your network interface name):
iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
Enable clamp-mss-to-pmtu:
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Kernel parameters

Enable the following parameters in  /etc/sysctl.conf (or the equivalent on your Linux distro):
net.ipv4.ip_forward = 1
net.ipv4.conf.default.proxy_arp = 1
net.ipv4.conf.default.arp_accept = 1
net.ipv4.conf.default.proxy_arp_pvlan = 1

Reboot the server to make them effective.

StrongSwan configuration

Create ipsec.secrets in your StrongSwan configuration directory (in my case it is /usr/local/etc/ipsec.secrets), insert the following content:
: PSK "password1"
user1 : EAP "password2"
user2 : EAP "password3"
We are using pre-shared key to authenticate clients. "password1" is the gateway password, "user1" and "user2" are usernames, "password2" "password3" are their passwords.
Modify ipsec.conf in your StrongSwan configuration directory (in my case, /usr/local/etc/ipsec.conf), replace its content by:

config setup
    strictcrlpolicy=no

conn %default
   ikelifetime=24h
   keylife=24h
   rekeymargin=9m
   keyingtries=10
   keyexchange=ikev2
   dpdaction=clear
   dpdtimeout=3600s
   dpddelay=3600s
   compress=yes

conn rem
   rekey=no
   leftsubnet=0.0.0.0/0
   leftauth=psk
   leftid=54.252.93.227
   right=%any
   rightsourceip=192.168.2.100/29
   rightauth=eap-mschapv2
   rightsendcert=never
   eap_identity=%any
   auto=add


Configurations must be copied exactly, preferably letter by letter. Any missing configuration will cause obscure connection issues.
Replace SERVER_PUBLIC_IP_ADDRESS by your server's public Internet IP address - it may not be left blank and must be accurate.

Modify strongswan.conf (in my case, /usr/local/etc/strongswan.conf)replace its content by:

charon {
   threads = 16
   dns1 = 8.8.4.4
   dns2 = 8.8.8.8
}

pluto {
}

libstrongswan {
}


You may substitute "8.8.8.8" or "8.8.4.4" with your favourite DNS server address.

Now you may start StrongSwan server.

Playbook configuration

Create a new VPN profile using the following connection details:
Profile Name: anything
Server Address: VPN server's public Internet address
Gateway Type: Generic IKEv2 VPN Server
Authentication Type: EAP-MSCHAPv2
Authentication ID Type: IPv4
MSCHAPv2 EAP Identity: anything, this field does not matter
MSCHAPv2 Username: user1 (username specified in ipsec.secrets)
MSCHAPv2 Password: password2 (user password specified in ipsec.secrets)
Gateway Auth Type: PSK
Gateway Auth ID Type: IPv4
Gateway Preshared Key:  password1 (the PSK password specified in ipsec.secrets)
Perfect Forward Secrecy: not checked
There is no need to change any "Advanced" configurations.
And there you go! Your VPN server for Playbook should be working by now!

If you wish to create VPN profile on Blackberry 10 (Blackberry Z10 or Blackberry Q10) devices, the configuration is almost identical, except that Authentication ID Type has to be set to "Email Address" rather than "IPv4", Email address in the VPN profile can be anything.

There is a known bug in Blackberry 10 will refuse to attempt the VPN connection when Authentication ID Type is IPv4 by always returning an "Unknown Error".

Additional information

The other tutorials (which contain some inaccuracies):
http://kingtut666.wordpress.com/2011/04/24/vpn-on-playbook/
http://richardwall.info/?page_id=218
Feel free to leave a comment should you have any trouble with the setup or connection.

Sunday, 4 November 2012

Learn more about a programming language by making something more useful

Inspired by this useful post: Learn a Programming Language Faster by Copying Unix. Here I present to you the idea of learning a programming language by making something more useful, which will give you more comprehensive experience about the new language.

The example here is my pet project Aurinko, a quite feature complete document database engine for me to practice and learn Clojure, while being very small and easy (< 800 LOC).

The features of Aurinko and related programming language features which I learned and practiced:
  • Collection management
    Exception handling, file read/write, protocol, type, mutable and immutable type members.
  • Document management
    Memory mapped file, dictionary structure, Java-Clojure interoperating, data type hints, string operations and using a data exchange format.
  • Index management
    Usage of mutable type members, anonymous functions and loop structures.
  • Handle complex query
    Vector, stack, set, common and specific collection functions, simulate a stack using vector.
  • Data durability
    Text file processing
  • Concurrency support
    Concurrency features in Clojure and locking.
  • Network enabled
    Socket programming, socket read/write, Clojure atoms and making an application protocol.
By less than 800 lines of code, I practiced almost all fundamental features of Clojure by working on the project, and the outcome is more useful - Clojure's first document database engine which works in file system rather than memory.

After all, the point which I am trying to make here is: While learning a new programming language, try to come up with an interesting project to work on, it has to be easy and its features have to be rich enough to cover the programming language's fundamentals. Using this approach may enhance your exposure to the language's features from a deeper perspective.

What do you think? Please leave a comment below!

Tuesday, 28 August 2012

Run Solaris 11 in VirtualBox

From my past experience, I can tell that so far VirtualBox is the ideal workstation virtualization solution for running Solaris 11 guests, especially VirtualBox guest additions support Solaris 11 guest operating system fairly well.

I have had a few troubles running Solaris 11 in VirtualBox, despite VirtualBox's excellent support to Solaris 11 guest. Here I write down the issue solutions.

Issue #1 - Solaris 11 has very poor installation / shutdown / boot performance
Solaris installation speed, shutdown and boot speed are very very poor compare to Linux guests, I am yet to find a solution for that - maybe Solaris has generally poor shutdown/boot speed? But disabling unnecessary system services (using svcadm and svcs utilities) and get rid of unused GNOME startup applications seem to help a little bit.

Issue #2 - Do not force umount CD/DVD in VirtualBox
Forcibly umount CD/DVD that is still being used by Solaris 11 will guarantee to cause Solaris 11 to become unresponsive, with 100% CPU usage.

Issue #3 -  Watch out when you install software packages
When I install a distribution, I always like to install as many software packages as I can... if you are same as me, be aware that Solaris 11 will kill itself if you install one of its "solaris" published software package. The package is called system/install/media/internal. Google search suggests that the package is used only for live DVD media and is not intended to be installed to an already completed Solaris 11 installation.

Issue #4 - Network traffic spike leads to 100% CPU usage and unresponsive Solaris 11
I have had this very weird issue - After my Solaris 11 was up for 2 to 3 hours, Gnome System Monitor showed a network transmission spike up to 4GBytes per second, and after that, Solaris reported 100% CPU usage that lasts 5 seconds, then CPU usage came down to normal for 5 seconds, and went to 100% for 5 seconds again - repeat like that until a reboot. This problem made my Solaris 11 virtual machine totally unusable. I discovered this small change which may help to solve the issue, replace the content of /usr/shjare/vpanels/java.policy with:
grant {
permission java.security.AllPermission;
};


Issue #5 - Eclipse randomly freezes

If you run Eclipse indigo in Solaris 11 in VirtualBox, your Eclipse may randomly freeze every few minutes, the reason is that Eclipse has used up all PermGen space allocated to it by default by Solaris's Hotspot JVM. To solve the issue, run Eclipse with the following command line arguments:
/opt/eclipse-3.7.2/eclipse -vmargs -XX:PermSize=128m -XX:MaxPermSize=384m -Xms128m -Xmx1024m

That will guarantee enough PermGen space for running Eclipse under Solaris 11.

Run CPAN in Solaris 11

Just some quick notes on running and using Perl and CPAN in Solaris 11.


First, you can install Perl 5.8 and/or Perl 5.12 in Soalris 11, they are available from publisher "solaris". You can have both 5.8 and 5.12 in your Solaris 11 and they will not conflict with each other.

Unlike most Unix/Linux distributions, cpan executable is not in $PATH in a Solaris 11. It is located at:
/usr/perl5/bin/
which is a symbol link to the default Perl version your Solaris uses:

lrwxrwxrwx 1 root root 10 2012-08-21 17:30 bin -> ./5.12/bin


Many CPAN modules require c compiler to build, CPAN will automatically use the C compiler at /bin/cc to build these modules. Default Solaris 11 installation does not have /bin/cc, so you have to install a C compiler.

Although you can find gcc3 or gcc4 from Soalris 11's package manager, but they are not capable of building CPAN modules (if you attempt to let CPAN use Solaris 11's gcc compilers, many modules will report compilation failure.)


The solution is to download and install Solaris Studio - it comes with C, C++ and Fortran compilers. After you have Solaris Studio installed, make a symbol link in /bin/ to the C compiler executable from Solaris Studio:

sudo ln -sf /bin/cc /opt/solarisstudio-12.3/cc


After created the cc symbol link, you may run cpan at /usr/perl5/bin/cpan

If you are installing a CPAN module that comes with executables - such as Module::Starter or Perl::Critic, you will find those executables at /usr/perl/bin/


Refer to my another post Solaris System Wide PATH and Super User PATH if you wish to put /usr/perl/bin to system wide PATH.

Sunday, 5 August 2012

Install VMware tools in FreeBSD 9


As of VMware workstation 8.0.3, although the official vmtools for FreeBSD can be installed in FreeBSD guest, but few features are not working well: guest screen autofit, mouse integration and HGFS drivers are totally not working. If you are having the same issue, this post may help you.


(Begin from a clean installation of FreeBSD)
Install xorg and your desktop environment of choice (XFCE4 for example):
# pkg_add -r xorg xfce4

Make sure that you do not have any existing vmtools installation. 
Install open-vm-tools from pre-compiled packages:
# pkg_add -r open-vm-tools


open-vm-tools package does not have VM video driver and VM mouse driver, so the following files have to be copied into your FreeBSD guest from the official FreeBSD vmtools ISO image. Multiple versions of the following files are placed in sub directories in the ISO image, where the directories are named by Xorg versions and system architecture (32 or 64bit), so pick your files carefully:

vmware_drv.la
vmware_drv.so

vmwlegacy_drv.la
vmwlegacy_drv.so
vmmouse_drv.la
vmmouse_drv.so


Place vmware_drv.la(and .so) and vmwlegacy_drv.la(and .so) inside /usr/local/lib/xorg/modules/drivers/ in your FreeBSD installation.



Place vmmouse_drv.la(and .so) inside /usr/local/xorg/modules/input/

Now our system has everything it needs to run vmtools. Next step is configuration.



# Xorg -configure
# cp /root/xorg.conf.new /etc/X11/xorg.conf



Edit your /etc/X11/xorg.conf according to the following text, pay special attention to the bold parts:



Section "ServerLayout"
   Identifier "X.org Configured"
   Screen 0 "Screen0" 0 0
   InputDevice "Mouse0" "CorePointer"
   InputDevice "Keyboard0" "CoreKeyboard"
EndSection



........

Section "InputDevice"
      Identifier "Mouse0"
      Driver "vmmouse"
      Option "Protocol" "auto"
      Option "Device" "/dev/sysmouse"
      Option "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
      Identifier "vmware"
      VendorName "VMware, Inc"
EndSection

Section "Device"

      Identifier "VMware SVGA"
      Driver "vmware"
EndSection

Section "Screen"
      Identifier "Screen0"
      Device "VMware SVGA"
      Monitor "vmware"
     ...........
EndSection

To summarize the changes to xorg.conf file:

Screen 0 is on monitor "vmware" driven by "vmware" video driver.
Mouse 0 is driven by vmmouse driver.


The changes above enable guest auto-fit and mouse integration.


Next we need to configure some vmware modules to be enabled upon boot, edit your /etc/rc.conf and append the following lines:



# DBus and HALd
dbus_enable="YES"
hald_enable="YES"
# VMware tools
vmware_guest_vmblock_enable="YES"
vmware_guest_vmhgfs_enable="YES"
vmware_guest_vmmemctl_enable="YES"
vmware_guest_vmxnet_enable="YES"
vmware_guestd_enable="YES"


Do not miss the "dbus" and "hald" lines, although they're not related to vmtools, but you need them to run a desktop environment.



Reboot FreeBSD 9.


Follow the instructions here to bring up your desktop environment/window manager:

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/x11-wm.html



Enter your desktop environment.
(for XFCE4, I do: % startx)



Test your mouse and keyboard and verify that they're working. However, you still do not have clipboard sharing, autofit guest, drag & drop yet, watch the next step:


Yes, you must have vmware-user-suid-wrapper as a startup application. That app gives you all the vmtools features. Notes on this:

- Alternatively, if you do not wish it to be run automatically, you can start a terminal application and type:
nohup vmware-user-suid-wrapper &
And you may quit the terminal any time (because nohup).



Note that:
- Sometimes vmware-user-suid-wrapper prints a few error or warnings, ignore them.
- Any user can run vmware-user-suid-wrapper (you don't have to be root to run it)
- Put vmware-user-suid-wrapper in /etc/rc.local did not work for me



Reboot and re-enter your desktop environment, make sure you enabled 3D acceleration in your virtual machine settings. Upon re-entering your desktop, everything should work just fine, you can even enable compositing (visual effects) as shown in the screenshot following:






BTW you can install firefox by
# pkg_add -r firefox


Good luck and have fun

Facepalmed by Oracle Solaris 11

Oracle Solaris 11 does not play nice to me, here is what I have encountered, all under the default installation and default system configuration in a VirtualBox:
  1. Very poor disk performance during package installation - Windows reports that VirtualBox causing disk queue to go up to > 6.
  2. Causing Windows network related system services to constantly use > 6% CPU.
  3. Very poor shutdown and bootup performance - takes 5 minutes to shutdown for the first time, and takes 5 minutes to boot up for the first time. Consequent shutdown and bootups take about 2 minutes.
  4. Killed itself after I installed a software package from publisher "solaris", later I learned that  the particular package should be installed to the system. Then the system could only boot into single user mode and /var became totally corrupted. If a "solaris" published software package is gonna kill Solaris, why allowing user to install it?
  5. A software package by "Solaris" has unresolvable dependency problem.
  6. After installing some programming tools, all not-installed software packages disappeared from Package Manager.
  7. Very often after screensaver is triggered, gnome no longer comes back, causing massive IO and after 10+ minutes, gnome restarts itself.
  8. Uses  > 4% of CPU even when idling.
  9. Still does not support pptp or openVPN.
I have been using Solaris 10 for software development, it runs smooth and fast. I have installed Solaris 11 for more than 5 times, each time it managed to kill itself in different ways.

Bye-bye Solaris 11, you are not friendly to your user.

Clojure Counterclockwise - "Problems encountered while setting project description"

Recently, I imported my Clojure Counterclockwise project into Eclipse, when I tried to create a run configuration, I got an error saying:

"Problems encountered while setting project description"

Error Log suggests little more information about the error:

"Problem occurred when invoking code from plug-in org.eclipse.jface"

Not entirely sure about how jface is preventing me from creating a run configuration, Google search doesn't help, so I figured out my own solution.

After the project is imported into workspace, do the following:

  1. If using Leiningen, do a "lein clean" in your project directory
  2. Right click project, "Clojure" -> "Remove Clojure Support"
  3. In your project directory, rm -rf classes/ target/ bin/
  4. Right click project "Leiningen Dependencies", "Build Path" -> "Remove from Build Path"
  5. Create your Clojure run configuration, and the error dialog no longer appears.
  6. After created run configuration, add Clojure support back into the project by right clicking project and "Configure" -> "Convert to Clojure project"
  7. Right click Clojure project and "Leiningen" -> "Reset project configuration"
When you enter Run Configuration dialog again, Eclipse will no longer give you the error, and your Clojure project shall run just fine.

Friday, 20 July 2012

Install VirtualBox Guest Addons in Solaris 11

It is easy to install VirtualBox Guest Addons in Solaris 11. The following steps assume that Solaris 11 has only just been installed.

Step 0 - Make sure that no DVD/CD image is currently assigned to the Solaris 11 virtual machine. Boot it and from VirtualBox's "Devices" drop down menu, choose "Install Guest Addons"

Step 1 - Once you enter Solaris desktop, go to terminal and change root password by "sudo passwd root". You will encounter three password prompts - first prompt asks for current logged in user's password, second and third prompts ask for new root password.

Step 2 - Change current working directory to VirtualBox Guest Addon CD image's directory, which is under /media/<your VirtualBox Guest Addon CD version>/. Then make sure that you are in the correct directory by typing "ls" and confirm the existence of "autorun.sh"

Step 3 - Run "sudo ./autorun.sh"

A new terminal will be launched and the remaining of the installation process is fully automatic. Shutdown (not reboot) your Solaris virtual machine, remove VirtualBox Guest Addon disk image from the virtual machine's CD drive, then boot the virtual machine, and you shall enjoy all the fantastic features of Guest Addons!

Note that:
Force un-mounting CD/DVD images using VirtualBox may cause Solaris 11 to lose responsiveness completely, and that is why I recommended shutting down Solaris 11 to replace/remove CD/DVD images.

To use VirtualBox Shared Folders:
  1. Specify the folder which you would like to share with Solaris in the virtual machine's Settings dialog.
  2. Reboot (or boot) your Solaris virtual machine.
  3. Exchange files with host operating system in /mnt/sf_<your_shared_folder_name>/