Friday, November 11, 2011

Using VirtualBox on Ubuntu 11.10

Ubuntu is my regular development environment and to test webapps on Internet Explorer, I use Windows running in VirtualBox. Installing VirtualBox is easy, since you can get it from the Ubuntu Software Center.

To make it really useful, you should install Guest Additions. This enables copy/paste between Ubuntu and Windows, and easy transfer of file by mounting a Ubuntu folder into Windows. You should be able to install Guest Additions by selecting the Devices/Install Guest Additions. However, I get an error message:

Failed to download the VirtualBox Guest Additions CD image from http://dlc.sun.com.edgesuite.net/virtualbox/4.1.2_Ubuntu/VBoxGuestAdditions_4.1.2_Ubuntu.iso.
Error downloading http://dlc.sun.com.edgesuite.net/virtualbox/4.1.2_Ubuntu/VBoxGuestAdditions_4.1.2_Ubuntu.iso - server replied: Not Found

Apparently, the ISO used to be available from SUN, and is probably shutdown after the Oracle merger. After some googling, I found that you can download the ISO manually here:

http://download.virtualbox.org/virtualbox

After downloading, just mount this ISO as a CD in the VirtualBox settings, boot up Windows and startup the installation yourself. After that, copy/paste and mounting host folders should work.

Monday, November 7, 2011

Add Eclipse to Ubuntu Unity lancher

Just like many other users of Ubuntu, I upgraded a few weeks ago to Ubuntu 11.10 "Oneiric Ocelot". Although the new Unity launcher takes a little time to get used to and has a few quirks, I still like it overall. It takes minimal amount of precious screen real estate and I find the use of the "Windows key" to start applications and find files very productive.

As a software developer I use Eclipse and I like to install some other tools manually under my home directory somewhere.

Add Eclipse to Launcher

To startup Eclipse, I just used the file manager and double clicked on the Eclipse executable. This gets tiresome really quickly. To integrate my self-installed Eclipse into the Unity launcher, you can create a configuration file that will tell the launcher how to startup a custom application like Eclipse.

Create a file with this contents and change the paths to where you installed Eclipse:

[Desktop Entry]
Comment=Eclipse JEE
Exec=/home/koert/software/eclipse-indigo-jee/eclipse
Icon=/home/koert/software/eclipse-indigo-jee/icon.xpm
Name=Eclipse JEE
Path=/home/koert/software/eclipse-indigo-jee
Type=Application
Terminal=false

Save this file as Eclipse.desktop in the .local/share/applications directory in your home directory.

Now, when you want to startup Eclipse, use the launcher (press the windows button) and enter Eclipse. The launcher should display the Eclipse icon, which you can use to start Eclipse. You will see the icon in the dock and you can keep this in the dock.

Start with specific workspace

When you use multiple workspaces, you can choose the workspace when Eclipse starts up by configuring items on the icon so that you can start a specific workspace.

You can add Shortcut Group items, which you must add to the X-Ayatana-Desktop-Shortcuts property.

This is an example with an option to choose a workspace and two options with specific workspaces:

[Desktop Entry]
Comment=Eclipse JEE
Exec=/home/koert/software/eclipse-indigo-jee/eclipse
Icon=/home/koert/software/eclipse-indigo-jee/icon.xpm
Name=Eclipse JEE
Path=/home/koert/software/eclipse-indigo-jee
Type=Application
Terminal=false
X-Ayatana-Desktop-Shortcuts=ChooseWorkspace;Workspace1;Workspace2

[ChooseWorkspace Shortcut Group]
Name=Choose workspace
Exec=/home/koert/software/eclipse-indigo-jee/eclipse
TargetEnvironment=Unity

[Workspace1 Shortcut Group]
Name=Privilege trunk
Exec=/home/koert/software/eclipse-indigo-jee/eclipse -name "Trunk" -data /home/koert/project/pretium/workspace
TargetEnvironment=Unity

[Workspace2 Shortcut Group]
Name=Privilege branche
Exec=/home/koert/software/eclipse-indigo-jee/eclipse -name "Branch" -data /home/koert/project/pretium/workspaces/branch-prod
TargetEnvironment=Unity

This saves me a little bit of time to startup Eclipse in the workspace that I want.

Wednesday, September 7, 2011

Quickly update your project version with Maven

When you want to update the version of your project, you can edit the pom.xml file and change the version by hand. When you have a project with multiple sub projects, this is time consuming and error prone.
Maven has a very useful utility to quickly update the version of your project, you can just run this Maven command:
mvn versions:set -DnewVersion=1.2.0-SNAPSHOT

This will update the version of your current project and its sub projects to "1.2.0-SNAPSHOT". This will save the previous version in backup files so you can revert back with this command:
mvn versions:revert

If you are happy with the results and want to get rid of the backup files, just do a commit with:
mvn versions:commit

Thursday, May 12, 2011

Using GIT as SubVersion (SVN) client

Install git-svn in Ubuntu

All git-* commands are implemented in Ubuntu with the git command: 'git-svn' is in Ubuntu 'git svn', notice the space.

Checkout

Do a checkout from SVN with
git svn clone -s -r [revision] [SVN URL] [new directory]
The [SVN URL] is the root of your SVN repository, the remote directory that contains your trunk, tags and branches subdirectories. The [revision] is the SVN revision number from which you want to retrieve history from. You may want to limit the history, because it takes time to retrieve all of the history from SVN. Example:
git svn clone -s -r 198 https://nextaction.googlecode.com/svn nextaction

Update from SVN

To update your local files from SVN, execute:
git svn rebase
If the update refuses to pull the changes from SVN and displays a message with "needs update", you probably made changes that you have not commited yet. Apparently, you must commit your changes locally first

Commit to GIT

When you make changes to your local files, you can commit them with:
git commit -a -m "Commit message"

Commit to SVN

This will only commit changes to your local GIT repository, to commit (or "push" in the GIT jargon) to SVN, use:
git svn dcommit

Tuesday, March 29, 2011

Creating a reusable layout component in Android

Let us say that we want to use a common layout in several places in your user interface. Something like a box with a label and value text view vertically layed out. The application uses the same label/value TextView in 3 different places.

This is the common label/value layout component (file: layout/dashboard_item.xml):
<LinearLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  
     <TextView android:id="@+id/label"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_weight="0"
         android:gravity="center_horizontal"
         style="@style/label"
     />
     <TextView android:id="@+id/value"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:layout_weight="1"
         android:gravity="center"
         style="@style/output"
     />
</LinearLayout>
We want to use it in a screen definition (file: layout/home.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:labelValue="http://schemas.android.com/apk/res/net.kazed.sailor"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"
      style="@style/screen"
      >

    <net.kazed.sailor.view.LabelValueItem android:id="@+id/vmg"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:layout_weight="1"
       labelValue:label="@string/vmg"
    />
    
   </LinearLayout>
</RelativeLayout>
Here we reuse the label/value custom component implemented by the LabelValueItem class. This component has one custom attribute: "labelValue:label". Notice that this attribute has a namespace that corresponds with the package name of the Android application (defined in AndroidManifest.xml). The component class retrieves the value of the custom attribute and uses it to set the text of the label TextView (file: src/net/kazed/sailor/view/LabelValueItem.java):
public class LabelValueItem extends LinearLayout {
   
   public LabelValueItem(final Context context, final AttributeSet attrs) {
      super(context, attrs);
      LayoutInflater.from(context).inflate(R.layout.dashboard_item, this, true);

      TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.labelValue, 0, 0);

      TextView label = (TextView) findViewById(R.id.label);
      String labelText = array.getString(R.styleable.labelValue_label);
      if (labelText != null) {
         label.setText(labelText);
      }

      array.recycle();
   }

}
To make it all work, the application must define the custom attribute (file: values/attr.xml):
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <declare-styleable name="labelValue">
      <attr name="label" format="string" />
   </declare-styleable>
</resources>

Monday, February 21, 2011

Error messages for required fields in JSF 1.2

JSF 1.1

When you have required fields in your JSF page, you simple add the required="true" attribute to the inputField and the user will get error message when user the field the field blank.
<h:inputText id="accountnumber" value="#{accountSetting.accountNumber}"
  required="true" />
This is all great, since we don't have to do much as a developer. However, the user gets an ugly error message: "accountForm:accountnumber: Validation Error: Value is required." This message is customizable by overriding this message in your message bundle and is pretty limited in how customized you want it to be.

JSF 1.2

JSF 1.2 and later makes it easier to create custom error messages for required fields, just add the requiredMessage attribute:
<h:inputText id="accountnumber" value="#{accountSetting.accountNumber}"
  required="true" requiredMessage="Account number is required" />
When the user has forgotten to enter something in this field, the JSF framework will display the error message supplied with the requiredMessage attribute. To supply translations for different languages, you can put the message in a resource bundle. Note that you must configure this resource bundle in faces-config.xml like this:
<application>
  <!-- ... -->
  <resource-bundle>
    <base-name>com.example.messages</base-name>
  <var>bundle</var>
  </resource-bundle>
</application>
This makes it possible to use the configured variable "bundle" anywhere in your pages, including the requiredMessage:
<h:inputText id="accountnumber" value="#{accountSetting.accountNumber}"
  required="true" requiredMessage="#{bundle.error_required_accountNumber}" />
I have found that the old way of using the loadBundle JSF component does not work with requiredMessage. The configured resource-bundle in faces-config.xml is much neater anyway.

Monday, January 3, 2011

Getting started with GIT

I recently started working on a new project and decided to try out the source repository GIT. As a long time user of CVS and Subversion (SVN), these distributed repositories take a little time getting used to.
As long as you use it yourself in a one man project, a distributed repository is almost the same as CVS and SVN. You check code out, make modifications and commit. The major difference is that you then "push" your commits to another repository, usually a remote server.

Create a local repository

To get started, after installing GIT, you can create a repository with the "init" command.
cd /path/to/repository
git init

Make modifications

Just like CVS and SVN, you can add/modify/delete files and commit them.
git add readme.txt
git commit -a -m "added readme text"
Note that this commit is stored locally, it is not committed to a central server.

Copy a repository

You can create a copy of a local repository with the "clone" command. This way you can locally make a branch.
cd /path/to/workspace
git clone /path/to/repository

Shareable repository

To create a sort of "central" repository like CVS or SVN, you can create a shareable repository with the "init" command. Do this on your server.
cd /path/to/repository
git init --bare --shared

Checkout with SSH

I use SSH to "checkout" from the remote repository, do this on your client.
cd /path/to/workspace
git clone ssh://myserver/path/to/repository
This makes a copy of the remote repository to my local workspace. Here I can make modifications and commit them. GIT will store your commit locally until you "push" this to the central repository.
git add readme.txt
git commit -a -m "added readme text"
git push origin master
This last command will update the remote repository with your commits.

See also