Eclipse: An Empty 'Available Software' List

The Problem

I recently (reluctantly) installed Eclipse on my Linux development box (Ubuntu 9.10) for the first time in over a year. I quickly ran into problems when trying to view and install available plug-ins on the 'Available Software' list (available from the menu: HelpInstall New Software...). The available software list appears to be empty, however, it seems that it is actually not being painted correctly.

A quick search pulled up a bug report that suggests a problem with Eclipse's use of the GTK, and a little more searching found an explanation about mixing calls through the GTK with calls to the native windowing system.

The Solution

The solution is to make sure all Eclipse GUI calls go directly to the native windowing system, avoiding the mix of native and GTK calls. This involves setting the GDK_NATIVE_WINDOWS shell environment variable. If starting eclipse from the command line, then this can be done as follows:

$ export GDK_NATIVE_WINDOWS=1
$ eclipse

If starting from a desktop short-cut or similar, then rename the eclipse executable to, say, eclipse.bin and create the following shell script, named eclipse, in the same directory:

#!/bin/bash

export GDK_NATIVE_WINDOWS=1
$(dirname $0)/eclipse.bin

Be sure to allow users with the requisite permissions to execute this script - from the command line:

$ chmod ug+x eclipse

Ownership of the new script file may also need changing:

$ sudo chown $(ls -l eclipse.bin | awk '{OFS=":"; print $3,$4}') eclipse

(That's the long way round, but it saves a little explaining and introduces an interesting use of awk!)

Eclipse Again, sigh! - An Aside

I switched to Netbeans a while ago, having grown weary of the bugs I was encoutering in Eclipse - I find Netbeans to be extremely stable and trouble-free, by-the-way.

I installed Eclipse again recently in order to take advantage of the Android Development Tools (ADT) plug-in for Eclipse and soon faced having to deal with the bug described above. I'd like to get on with the job of developing decent software and an IDE that requires trouble-shooting, work-arounds and restarts takes me away from that and breaks concentration. That's frustrating!

I'm inclined to attribute this bug to quality issues in the Eclipse code-base. That's based upon using Eclipse for a number of years (primarily for Java and C++ development) and seeing it become increasingly unstable. The explanation regarding mixing GUI calls may also add weight to this view - Eclipse would seem to breaking Demeter's Law in an interesting way by going extra lengths to by-pass the GDK layer from within the JRE.

My recent experience with Eclipse has done nothing to bring me back to using it again, and so I'll continue to use the ever improving Netbeans where possible.

Share:

PHP Output to Syslog on Ubuntu

There are just a few things you need to know in order to output trace or error information to syslog on an Ubuntu system (the following is probably true for other Debian-based distributions, too) from PHP.

  1. Set error logging to syslog in php.ini (the system-wide php.ini can be found at /etc/php5/php.ini):
    error_log = syslog
    
  2. Restart Apache:
    $ sudo /etc/init.d/apache2 restart
    
  3. Use the error_log() function to output your error messages.
  4. View the output of error messages:
    $ tail -f /var/log/syslog
    The -f flag causes new messages to be appended to the output of tail.
Share:

Selecting A Free Software License

Motives

I've been stuck in the world of open source software licensing recently. I've written a reasonable amount of software for use by my company, getpepper™, and I would be happy to make some of that software open source. Although I'm inclined to help others, and generally hope to do things that are considered to be socially useful, my choice to open source isn't purely altruistic. Certainly I hope it benefits others as it benefits getpepper™ by its use. But I also hope that getpepper™ and maybe me, individually, will benefit from the wider exposure that open sourcing can bring.

The initial items of software that I'm considering open sourcing are plugins for WordPress and jQuery, both of which currently use the GPL version 2 license. There is a view that developing extensions for at least one of these platforms means that those extensions themselves become GPL'd. I want to understand the commercial implications of this as it effects my company when it releases its software under an open source license - and here I probably mean the GPL, or a GPL-compatible license.

Concerns

So with the above in mind here are a couple of my concerns.

  • As the original author and copyright holder of the software, can I recover that software to apply a different, non-GPL-compatible license to it?
  • Are the rights of the original author any different to the rights of any other user of the software?

Maybe I'm being overly cautious and a little edgy about committing my time and hard work to an open source license, or maybe I'm not really giving too many of my rights away. I'm not sure as I'm not a lawyer and prefer to spend my time writing software, not figuring out the intricacies of licensing law - which seems pretty dull compared to writing most, but not all, types of software. Anyway, hopefully some of my future posts will reflect a more legally aware view!

Share:

A Quick JDBC How-To

In order to access a persistence store using JDBC, it's necessary to load the JDBC driver using the Class class's static method forName(). Once the JDBC driver has been loaded, it should be possible to make a connection to a database managed by the DBMS. Here's how the postgresql JDBC driver is loaded (don't forget to make sure the JDBC driver jar file is either on the class path, or referenced directly), and then used to get a database connection:

// Load the driver class
Class.forName("org.postgresql.Driver");

// Obtain a connection to the DBMS
java.sql.Connection connection =
    java.sql.DriverManager.getConnection(
        "jdbc:postgresql://localhost/dbname",
        "username",
        "password");

Once you have a connection you can start manipulating the database. Use the java.sql.Statement class to do this with the java.sql.ResultSet to manage the results of executing a statement.

There are two other types of statement available, namely CallableStatement and PreparedStatement, which offer stored procedure statements and preparsed SQL statements, repectively. These have the advantage of reducing the overhead of parsing executed SQL at run-time. The PreparedStatement is likely the more useful due to its simplicity and improved efficiency. Here's an example of its use:

try {
    PreparedStatement ps = null;

    ps = c.prepareStatement("INSERT INTO authors VALUES (?, ?, ?)");
    ps.setInt(1, 495);
    ps.setString(2, "Light-Williams");
    ps.setString(3, "Corwin");

    ps.executeUpdate();
} catch (SQLException se) {
    System.out.println(
        "We got an exception while preparing a statement:" +
        "Probably bad SQL.");
    se.printStackTrace();
    System.exit(1);
}

After executing an SQL statement, obtain the results set data, including the names and types of columns that have been updated by a statement, using an instance of ResultsSetMetaData obtained from the ResultsSet instance.

Similarly the DatabaseMetaData can be used to obtain information such as the catalogues available from the connected database, the producer of the database and the user who is used for the connection. Get an instance of the DatabaseMetaData via the Connection object instance through the getMetaData() method.

It's worth noting a few points about the results set returned by executing an SQL statement. Firstly the returned ResultsSet object starts off pointing to the the position prior to the first record. This means that the next() method must be called on the ResultsSet object in order to get the first record. Also, there is no way of finding out the number of records held by a returned ResultsSet instance except by stepping through it and counting the number of records. Finally, in multi-threaded applications ensure that each thread uses its own ResultsSet objects.

Tags:
Share:

Data Back-up Bash Script

Data Back-up Requirement

Last year (2008), when getting processes in place for our new web design and software development business, getpepper™, I put together an all important data back-up procedure. My aim was, in the worse case, to ensure that we could restore all but the last few days-worth of data for our own systems and that of our clients.

We mostly use open source systems and tools to create and manage our websites and write our software, with the Ubuntu Linux distribution forming the platform upon which our server-based systems (source control (Subversion), issue tracking (Trac), CRM, etc.) and some of our desktop systems run.

After some research on Linux-based back-up facilities I settled on using a (Bash) shell script that would allow us to run a regular back-up cycle using external portable hard disks. The weekly back-up shell script, which saves to USB hard drives, is based upon a script provided by Mike Rubel.

The Script

The script uses the rsync tool to provide the incremental functionality of the back-up. Here's the adapted script that we use.

# ============================
# Author: Paul Pepper (though see description below for credits)
# Created: 6 November 2008
# Description:
#   Rotating-snapshot utility adapted from Mike Rubel's make_snapshop.sh which
#   can be found at http://www.mikerubel.org/computers/rsync_snapshots/
#   Basically, this script performs rotating backup-snapshots of /home whenever
#   it is called.
# ============================


#!/bin/bash

unset PATH # suggestion from H. Milz: avoid accidental use of $PATH

# ============================
# System commands used by this script
# ============================

ID=/usr/bin/id
ECHO=/bin/echo

MOUNT=/bin/mount
UMOUNT=/bin/umount
RM=/bin/rm
MV=/bin/mv
CP=/bin/cp
TOUCH=/bin/touch
RSYNC=/usr/bin/rsync

# ============================
# File names and locations
# ============================

MOUNT_DEVICE=/dev/sdb1
MOUNT_POINT=/media/sdb
BACKUP_TO_DIR=/backup/
BACKUP_FROM_DIR=/home
SNAPSHOT=snapshot
EXCLUDES=
BACKUP_TO_PATH=${MOUNT_POINT}/${BACKUP_TO_DIR}/${SNAPSHOT}

# ============================
# The script
# ============================

# Make sure we're running as root
if [ `$ID -u` != '0' ]; then
    $ECHO "$0 must be executed as root.  Exiting!"
    exit 1
fi

# Attempt to mount the backup device, else abort
$MOUNT -o rw $MOUNT_DEVICE $MOUNT_POINT
if [ $? -ne 0 ]; then
    $ECHO "$0: Could not mount $MOUNT_DEVICE on $MOUNT_POINT as readwrite"
    exit 1
fi

# Step 1: delete the oldest snapshot, if it exists:
if [ -d ${BACKUP_TO_PATH}.3 ] ; then
    $RM -rf ${BACKUP_TO_PATH}.3
fi

# Step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d ${BACKUP_TO_PATH}.2 ] ; then
    $MV ${BACKUP_TO_PATH}.2 \
        ${BACKUP_TO_PATH}.3
fi

if [ -d ${BACKUP_TO_PATH}.1 ] ; then
    $MV ${BACKUP_TO_PATH}.1 \
        ${BACKUP_TO_PATH}.2
fi

# Step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d ${BACKUP_TO_PATH}.0 ] ; then
    $CP -al ${BACKUP_TO_PATH}.0 \
            ${BACKUP_TO_PATH}.1
fi

# Step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first.  If it were not so, this would copy over the other
# snapshot(s) too!
$RSYNC -va --delete --delete-excluded     \
    --exclude-from="$EXCLUDES"            \
    ${BACKUP_FROM_DIR} ${BACKUP_TO_PATH}.0

# Step 5: update the mtime of our most recent snapshot.
$TOUCH ${BACKUP_TO_PATH}.0

# Unmount the device to which we've written the backup
${UMOUNT} ${MOUNT_POINT}
if [ $? -ne 0 ]; then
    $ECHO "$0: Could not unmount ${MOUNT_POINT}"
    exit 1
fi

Here's an outline of our weekly back-up process:

  1. Grab one of the external hard disks.
  2. Attach hard disk to server via a USB connector.
  3. Log in to server as a regular user - don't su to root!
  4. Run the back-up shell script:
    $ sudo ./backup-snapshot.sh
            
  5. Disconnect hard disk and return to its place of safe-keeping!

And that's it!

All users who perform the back-up must have the necessary permissions to run the shell. I enforce this by adding those users as sudoers, only permitting privileged access to the back-up shell script. Here's the relevant parts of the sudoers file that grants that access - note that it is recommended that you use visudo when editing this file.

# User alias specification
User_Alias  BACKUP_USERS = ann, bill

# Cmnd alias specification
Cmnd_Alias  BACKUP_CMND = /somepath/backup-snapshot.sh, /bin/mount, /bin/umount, /bin/touch, /usr/bin/rsync

# Permit BACKUP_USERS to run the back-up script as root from all locations
BACKUP_USERS    ALL=(root) BACKUP_CMND
Share:
Subscribe to this blog rss news feed icon