Wednesday, October 6, 2010

Understanding Android SQLite Database

Because of the limited documentation of Android's database handling, I have spent days trying to understand the inner workings SQLite in an Android application. Debugging here, testing there, but in the end, going no where.

For those who are in a hurry to learn SQLite in Android, I have written this in order to share my discoveries and hope to help those who are impatiently wanting to understand Android's database handling

In order to demonstrate database creation, we will create an An android project that will take the a name and an age data and save it in SQLite database.

Make sure that you already have Eclipse with Android plug-in installed.

Let's start by creating an Android project by clicking File->New-Project.


Select Android Project from the list (you may have to expand Android to see Android Project)




Click the Next button to proceed.

Now fill in the project details using the following values:

Project Name = Android SQLite DemoBuild Target = Android 2.1
Application Name = SQLite Demo
Package Name = com.demo.sqlite
Activity = Main


Click Finish to create the project

Let's start with construction the UI. Open main.xml located in res/layout.

Replace the content with the following:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:stretchColumns="1">
    <TableRow>
        <TextView android:text="Name" />
        <EditText android:id="@+id/name" />
    </TableRow>
    <TableRow>
        <TextView android:text="Age" />
        <EditText android:id="@+id/age" />
    </TableRow>
    <TableRow>
        <Button android:id="@+id/saveButton"
            android:layout_span="2"
            android:text="Save"
        />
    </TableRow>
</TableLayout>




Save main.xml then open Main.java in src/src/com.demo.sqlite.

Type in the following:

package com.demo.sqlite;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Main extends Activity {
    private EditText name;
    private EditText age;
   
   
    private OnClickListener saveButtonClicked = new OnClickListener() {
       
        public void onClick(View v) {
            DBHandler dbHandler = new DBHandler(v.getContext());
            Long id = dbHandler.insertRow(name.getText().toString(), Integer.parseInt(age.getText().toString()));
            if (id != -1){
                Toast toast = Toast.makeText(v.getContext(), "Your data has been saved, successfully", Toast.LENGTH_SHORT);
                toast.show();
                name.setText("");
                age.setText("");
            }
        }
    };
   
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        name = (EditText) findViewById(R.id.name);
        age = (EditText) findViewById(R.id.age);
        Button saveButton = (Button) findViewById(R.id.saveButton);
        saveButton.setOnClickListener(saveButtonClicked);
    }
}


Save Main.java.


Now, create a new class under com.demo.sqlite and name it DBHandler.java. Type the following in the newly created class:

package com.demo.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;

public class DBHandler extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "demo.db";
    private static final String TABLE_NAME = "mytable";
    private static final String QUERY_CREATE_TABLE =
        "CREATE TABLE "
        + TABLE_NAME
        + "(id INTEGER PRIMARY KEY AUTOINCREMENT"
        + ",name TEXT"
        + ",age INTEGER);";
    private static final String QUERY_INSERT_ROW =
        "INSERT INTO "
        + TABLE_NAME
        + "(name, age)"
        + "values (?,?)";
   

   
    SQLiteDatabase db;
    SQLiteStatement stmtInsertRow;
   
   
    public DBHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        db = this.getWritableDatabase();
        stmtInsertRow = db.compileStatement(QUERY_INSERT_ROW);
    }

   
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(QUERY_CREATE_TABLE);
    }

   
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
   
   
    public long insertRow(String name, Integer age){
        stmtInsertRow.bindString(1, name);
        stmtInsertRow.bindLong(2, age);
        return stmtInsertRow.executeInsert();
    }

}




Let's trace the program execution to learn how Android handles SQLite databases first hand. Put breakpoints on the first line of all methods/functions of DBHandler. Now start debugging.

First Run:

Type in your name and age in the input boxes respectively. Click the save button when you are finished.

After clicking the save button the constructor for DBHandler is called when then DBHandler is initialized.

super(context, DATABASE_NAME, null, DATABASE_VERSION), Initializes DBHandler by calling SQLiteOpenHelperConstructor.

When the second line db = this.getWritableDatabase() is executed, the onCreate method is called. onCreate executes a query that will create your table.

After onCreate finishes, execution goes back to the constructor then creates the insert statement. Code continues to save the data that you have provided in the text boxes.

Notice that in this first run the onCreate method is called. It has been advised that you put your table creation query here. Do not worry thinking that every time the constructor is called the table creation query will be executed. You will know why it is best to put your table creation query here later.

Also notice onUpgrade method is not called during program execution.


2nd Run:

You may want to  close the emulator  and restart Eclipse. This is to demonstrate what will happen when Android phone or your Android application is restarted.



Now start debugging.

On the second run, constructor for DBHandler is again called.

When the second line db = this.getWritableDatabase() is executed, you will notice that onCreate method is NOT called. This just returns a reference to SQLiteDatabase object.


The next line creates the and insert statement and continues to run just like in the first run.

In this second run you will notice that onCreate method is never called. Android knows that the database is already created and thus skips calling the onCreate method.

Again the onUpgrade method is not executed.


3rd Run:

For the third run, edit DBHandler.java. Change the line

private static final int DATABASE_VERSION = 1;

to

private static final int DATABASE_VERSION = 2;

Save DBHandler.java. If you're the doubting kind, you may want to restart Eclipse and close the emulator.

 Start the debug.

 Step over the code until you reach

db = this.getWritableDatabase();

Notice that when you execute this line you will jump to onUpgrade method instead of onCreate method.

onUpgrade method deletes your table then calls onCreate to re-create your table.

After creating the table, execution goes back to DBHandler constructor. The codes continues to execute, inserting a data to the table and popping a notification the insert procedure went sucessfully.

Here, onCreate is only executed because onUpgrade called it. This is the recommended way of updating the database table.



In summary, the following should be noted:

- your database handler class should extend SQLiteOpenHelper.

 - SQLiteOpenHelper's onCreate method is the recommended place to put your table creation query.

- SQLiteOpenHelper's onCreate method is called/executed only when the database is first created. Android ignores this if the database already exist.

- To delete, change, or update the database table structure, it is recommended that you put the code inside SQLiteOpenHelper's onUpgrade function. Note that you have to change the database version to force the execution of onUpgrade function. It does not matter whether you increment or decrement database version as long as the new version number is different from the previous number the application is running on.



I hope this helps. Good luck!

Saturday, September 25, 2010

Running Eclipse on a Mac Network User Account

Original Post Date: Aug 17, 2010

ISSUE:

When running eclipse (galileo) using a Mac network user account a message “Workspace in use or cannot be created, choose a different one” always pops up. Then after clicking "OK", eclipse closes



SOLUTION:

Run eclipse with the following parameters:

-vmargs -Dosgi.locking=java.io


e.g.

./eclipse -vmargs -Dosgi.locking=java.io

OR

Add -Dosgi.locking=java.io in eclipse.ini.

eclipse.ini can be found by right clicking Eclipse.app and choosing "Show Package Content". Then go to Contents -> MacOS



REFERENCE:

http://www.spreendigital.de/blog/2010/03/26/eclipse-on-mac-os-x-workspace-error-on-nfs-mounts/comment-page-1/#comment-4486

Setting Up OpenVPN

This is a transfer from a blog dated Feb 23, 2009
consolidating...

Goal


To concentrate on getting a VPN up and running. Explanations are cut to the very minimum (for details read the OpenVPN HowTo).
This guide is done using an Ubuntu 8.04 for the server and client. The text in red may be modified to fit your configurations.


Server


Install


- log in to the server
- execute:

# apt-get install openvpn


Create CA


- execute:

# cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
# source ./vars
# ./clean-all
# ./build-ca


[[build-ca will prompt you for some values. Use the following as reference:]]

Country Name (2 letter code) [US]:PH
State or Province Name (full name) [CA]:MM
Locality Name (eg, city) [SanFrancisco]:Pasig
Organization Name (eg, company) [Fort-Funston]:DPI
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:DPI-VPN
Email Address [me@myhost.mydomain]:eman.de.guzman@gmail.com


[[this will create ca.crt and ca.key in /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/]]


Create Key & Certificate


- execute:
# cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
# ./build-key-server server

[[build-key-server will prompt you for some values. Use the following as reference (leave challenge password and optional company name blank):]]

Country Name (2 letter code) [US]:PH
State or Province Name (full name) [CA]:MM
Locality Name (eg, city) [SanFrancisco]:Pasig
Organization Name (eg, company) [Fort-Funston]:DPI
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) [server]:server
Email Address [me@myhost.mydomain]:eman.de.guzman@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'PH'
stateOrProvinceName :PRINTABLE:'MM'
localityName :PRINTABLE:'Pasig'
organizationName :PRINTABLE:'DPI'
commonName :PRINTABLE:'server'
emailAddress :IA5STRING:'eman.de.guzman@gmail.com'
Certificate is to be certified until Feb 23 02:17:50 2019 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated


[[build-key-server will create server.crt and server.key in /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/]]


Create Diffie Hellman parameters


- execute:

# cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
# ./build-dh

[[build-dh will create dh1024.pem in /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/]]


Configuration


- execute:
# cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
# cd /etc/openvpn
# gunzip server.conf.gz

- open /etc/openvpn/server.conf and change the following:

line 78
from ca ca.crt
to ca /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt

line 79
from cert server.crt
to cert /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/server.crt

line 80
from key server.key
to key /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/server.key

line 87
from dh dh1024.pem
to dh /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/dh1024.pem

- save and close /etc/openvpn/server.conf


Test


- execute:

# openvpn /etc/openvpn/server.conf

- the output should look something like (the line "Initialization Sequence Completed" indicates that everything is working):


Mon Feb 23 12:22:25 2009 OpenVPN 2.1_rc7 i486-pc-linux-gnu [SSL] [LZO2] [EPOLL] built on Jun 11 2008
Mon Feb 23 12:22:25 2009 Diffie-Hellman initialized with 1024 bit key
Mon Feb 23 12:22:25 2009 /usr/bin/openssl-vulnkey -q -b 1024 -m
Mon Feb 23 12:22:25 2009 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Mon Feb 23 12:22:25 2009 TUN/TAP device tun0 opened
Mon Feb 23 12:22:25 2009 TUN/TAP TX queue length set to 100
Mon Feb 23 12:22:25 2009 ifconfig tun0 10.8.0.1 pointopoint 10.8.0.2 mtu 1500
Mon Feb 23 12:22:25 2009 route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.8.0.2
Mon Feb 23 12:22:25 2009 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Mon Feb 23 12:22:25 2009 Socket Buffers: R=[110592->131072] S=[110592->131072]
Mon Feb 23 12:22:25 2009 UDPv4 link local (bound): [undef]:1194
Mon Feb 23 12:22:25 2009 UDPv4 link remote: [undef]
Mon Feb 23 12:22:25 2009 MULTI: multi_init called, r=256 v=256
Mon Feb 23 12:22:25 2009 IFCONFIG POOL: base=10.8.0.4 size=62
Mon Feb 23 12:22:25 2009 IFCONFIG POOL LIST
Mon Feb 23 12:22:25 2009 Initialization Sequence Completed


- press Ctrl+C to stop the test


Run


- execute:

# /etc/init.d/openvpn start

[[the init.d script for OpenVPN will look for .conf file in /etc/openvpn/ and use it as configuration file. This means that everytime you start the server it will start to listen for a vpn connection request.]]



Linux Client


Install


- log in to the linux client
- execute:

# apt-get install openvpn



Create Key & Certificate


- execute:

# cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
# mkdir keys
# chmod 700 keys
# source ./vars
# ./clean-all
# scp user@vpnserver_ip:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.key ./keys/.
# scp user@vpnserver_ip:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt ./keys/.
# ./build-key client

[[the lines
# scp user@vpnserver:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.key ./keys/.
# scp user@vpnserver:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt ./keys/.

aim to copy the certificate authority (ca) key and certificate from the server to the client. you can use other means to copy the files from the server to the client]]

[[build-key will prompt you for some values. Use the following as reference (leave challenge password and optional company name blank):]]


Country Name (2 letter code) [US]:PH
State or Province Name (full name) [CA]:MM
Locality Name (eg, city) [SanFrancisco]:Pasig
Organization Name (eg, company) [Fort-Funston]:DPI
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) [client]:client1
Email Address [me@myhost.mydomain]:eman.de.guzman@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'PH'
stateOrProvinceName :PRINTABLE:'MM'
localityName :PRINTABLE:'Pasig'
organizationName :PRINTABLE:'DPI'
organizationalUnitName:PRINTABLE:'IT'
commonName :PRINTABLE:'client1'
emailAddress :IA5STRING:'eman.de.guzman@gmail.com'
Certificate is to be certified until Feb 22 08:46:55 2019 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated


[[make sure CommonName value is different for each client]]
[[this will create client.crt and client.key in /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/]]


Configuration


- execute:

# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/
# cd /etc/openvpn

- open /etc/openvpn/client.conf and change the following:

line 42
from remote my-server-1 1194
to remote 111.111.111.101 1194

line 88
from ca ca.crt
to ca /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt

line 89
from cert
client.crt
to cert /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/client.crt

line 90
from key client.key
to key /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/client.key

- save and close /etc/openvpn/client.conf


Test


- make sure that UDP port 1194 on the server is open
- execute:

# openvpn /etc/openvpn/client.conf

- the output should look something like (the line "Initialization Sequence Completed" indicates that everything is working):


Tue Feb 24 16:58:07 2009 OpenVPN 2.1_rc7 i486-pc-linux-gnu [SSL] [LZO2] [EPOLL] built on Jun 11 2008
Tue Feb 24 16:58:07 2009 WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
Tue Feb 24 16:58:07 2009 /usr/bin/openssl-vulnkey -q -b 1024 -m
Tue Feb 24 16:58:08 2009 LZO compression initialized
Tue Feb 24 16:58:08 2009 Control Channel MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Tue Feb 24 16:58:08 2009 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Tue Feb 24 16:58:08 2009 Local Options hash (VER=V4): '41690919'
Tue Feb 24 16:58:08 2009 Expected Remote Options hash (VER=V4): '530fdded'
Tue Feb 24 16:58:08 2009 Socket Buffers: R=[110592->131072] S=[110592->131072]
Tue Feb 24 16:58:08 2009 UDPv4 link local: [undef]
Tue Feb 24 16:58:08 2009 UDPv4 link remote: 111.111.111.101:1194
Tue Feb 24 16:58:08 2009 TLS: Initial packet from 111.111.111.101:1194, sid=efff49ab 3322efb5
TueFeb2416:58:082009VERIFYOK:depth=1,/C=PH/ST=MM/L=Pasig/O=DPI/CN=DPI_CA/emailAddress=eman.de.guzman@gmail.com
TueFeb2416:58:082009VERIFYOK:depth=0,/C=PH/ST=MM/L=Pasig/O=DPI/CN=server/emailAddress=eman.de.guzman@gmail.com
Tue Feb 24 16:58:08 2009 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Tue Feb 24 16:58:08 2009 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Feb 24 16:58:08 2009 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Tue Feb 24 16:58:08 2009 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Feb 24 16:58:08 2009 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
Tue Feb 24 16:58:08 2009 [server] Peer Connection Initiated with 111.111.111.101:1194
Tue Feb 24 16:58:09 2009 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Tue Feb 24 16:58:09 2009 PUSH: Received control message: 'PUSH_REPLY,route 10.8.0.0 255.255.255.0,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5'
Tue Feb 24 16:58:09 2009 OPTIONS IMPORT: timers and/or timeouts modified
Tue Feb 24 16:58:09 2009 OPTIONS IMPORT: --ifconfig/up options modified
Tue Feb 24 16:58:09 2009 OPTIONS IMPORT: route options modified
Tue Feb 24 16:58:09 2009 TUN/TAP device tun0 opened
Tue Feb 24 16:58:09 2009 TUN/TAP TX queue length set to 100
Tue Feb 24 16:58:09 2009 ifconfig tun0 10.55.55.6 pointopoint 10.8.0.5 mtu 1500
Tue Feb 24 16:58:09 2009 route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.8.0.5
Tue Feb 24 16:58:09 2009 Initialization Sequence Completed


- press Ctrl+C to stop the test


Run


- execute:

# /etc/init.d/openvpn start


[[the init.d script for OpenVPN will look for .conf file in /etc/openvpn/ and use it as configuration file. This means that everytime you start the client it will establish a vpn with the server.]]



Windows Client


Install


- download OpenVPN's Windows Installer
- run downloaded file to start OpenVPN installation


Create Key & Certificate


- in a command window, execute the following:

C:\> cd "c:\Program Files\OpenVPN\easy-rsa"
C:\> init-config
C:\> vars
C:\> clean-all
C:\> pscp user@vpnserver_ip:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.key keys\.
C:\> pscp user@vpnserver_ip:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt keys\.
C:\> path=%PATH%;c:\Program Files\OpenVPN\bin
C:\> build-key client

[[the lines
C:\> pscp user@vpnserver_ip:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.key keys\.
C:\> pscp user@vpnserver_ip:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt keys\.

aim to copy the certificate authority (ca) key and certificate from the server to the client. you can use other means to copy the files from the server to the client]]

[[build-key will prompt you for some values. Use the following as reference (leave challenge password and optional company name blank):]]


Country Name (2 letter code) [US]:PH
State or Province Name (full name) [CA]:MM
Locality Name (eg, city) [SanFrancisco]:Pasig
Organization Name (eg, company) [Fort-Funston]:DPI
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:client2
Email Address [me@myhost.mydomain]:eman.de.guzman@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'PH'
stateOrProvinceName :PRINTABLE:'MM'
localityName :PRINTABLE:'Pasig'
organizationName :PRINTABLE:'DPI'
organizationalUnitName:PRINTABLE:'IT'
commonName :PRINTABLE:'client1'
emailAddress :IA5STRING:'eman.de.guzman@gmail.com'
Certificate is to be certified until Feb 22 08:46:55 2019 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated



Configuration


- still in the same command window, execute the following:

C:\> cd "c:\Program Files\OpenVPN\config\"
C:\> copy ..\sample-config\client.ovpn .
C:\> edit client.ovpn

change the following:

line 42
from remote my-server-1 1194
to remote 111.111.111.101 1194

line 88
from ca ca.crt
to ca c:/Program\ Files/OpenVPN/easy-rsa/keys/ca.crt

line 89
from cert
client.crt
to cert c:/Program\ Files/OpenVPN/easy-rsa/keys/client.crt

line 90
from key client.key
to key c:/Program\ Files/OpenVPN/easy-rsa/keys/client.key

- save and close "c:\Program Files\OpenVPN\config\client.conf"


Run


- make sure that UDP port 1194 on the server is open
- still in the same command window, execute the following:

C:\> cd "c:\Program Files\OpenVPN"
C:\> bin\openvpn config\client.ovpn

- when you see the line "Initialization Sequence Completed", this indicates that everything is working
- press Ctrl+Pause to stop OpenVPN



Reference


OpenVPN HowTo



Tuesday, August 17, 2010

Running Eclipse on a Mac Network User Account

ISSUE:

When running eclipse (galileo) using a Mac network user account a message “Workspace in use or cannot be created, choose a different one” always pops up. Then after clicking "OK", eclipse closes



SOLUTION:

Run eclipse with the following parameters:

-vmargs -Dosgi.locking=java.io


e.g.

./eclipse -vmargs -Dosgi.locking=java.io

OR

Add -Dosgi.locking=java.io in eclipse.ini.

eclipse.ini can be found by right clicking Eclipse.app and choosing "Show Package Content". Then go to Contents -> MacOS



REFERENCE:

http://www.spreendigital.de/blog/2010/03/26/eclipse-on-mac-os-x-workspace-error-on-nfs-mounts/comment-page-1/#comment-4486