Tuesday, December 16, 2014

FreeBSD on Raspberry Pi B+

It has been almost 10 years since I ran my own UNIX-like server at home. The last Debian machine died because of hardware failures. It was an old Pentium II machine. It started itching again a week ago. I wanted to run a server at home 24/7 at a very low cost. It would also be a great opportunity to refresh my C programming skills again.

I you think about low cost, then Raspberry Pi would undoubtedly come to mind. It's a very small but capable device. The costs of running it 24/7 is about 5 EUR per year. So I looked around online, and finally bought the model B+ with a nice translucent casing, a 1A power adapter, an HDMI cable, and a SanDisk Extreme 16GB MicroSD card. The total costs for the complete server setup: 70 EUR.

Now I had the hardware set. Next, I needed to select a nice OS image to put on the memory card. I narrowed it down to Raspbian, and FreeBSD. Raspbian is based on Debian, which I’m very familiar with. I've been running Debian for years. I really like their packaging system, and the minimal install. But I really wanted something closer to UNIX than Linux, so I went for FreeBSD.

Installation

Lucky me, the latest release supports Raspberry Pi. So I downloaded the image (FreeBSD-10.1-RELEASE-arm-armv6-RPI-B.img) from their site. This is how I put the FreeBSD image on the memory card. I used Mac OS X to do it. On the Mac, I changed to the root user, so I’m allowed to write to a device directly.

sudo su -

(Yes, you can also do "su", but SyntaxHighlighter rendered that command invisible.) Now I needed to determine the name of our memory card device. So I executed the following command, before inserting the memory card.

diskutil list

I memorized the list, and inserted the memory card. Now I executed the previous command again and checked that there is a new device in the list. This would then be my memory card device. On my computer, it was the “/dev/disk1” device. Now I unmounted the file system cleanly with:

diskutil unmountDisk /dev/disk1

Now I wrote the FreeBSD image directly to disk with the next command. Please be careful, and make sure the device is correct. Otherwise you risk damaging the existing file system used by your computer!

dd if=FreeBSD-10.1-RELEASE-arm-armv6-RPI-B.img of=/dev/disk1 bs=1m

After this, I ejected the card:

diskutil eject /dev/disk1

Now I inserted the memory card in the Raspberry Pi, and I connected the HDMI cable to my TV. The moment of truth: connect the USB power supply, and see if it boots!

Unfortunately, my TV screen remained black. So I double checked the cables and screen settings, but to no avail. FreeBSD didn’t boot. After some Google research, I found out there was probably something wrong with the boot/firmware files. So I replaced the following files on my memory card with the files downloaded from: https://github.com/kientzle/crochet-freebsd/tree/master/board/RaspberryPi/boot

  • bootcode.bin
  • fixup.dat
  • fixup_cd.dat
  • start.elf
  • start_cd.elf

That did the trick, Raspberry Pi booted successfully to a FreeBSD login prompt!

Post installation tasks

To be able to be root, I needed to be member of the “wheel” group:

pw user mod gin -G wheel

I also wanted the system date to be automatically synced. So I enabled the time daemon:

tzsetup (set local time zone)
echo 'ntpd_enable="YES"' >> /etc/rc.conf
echo 'ntpd_sync_on_start="YES"' >> /etc/rc.conf
service ntpd start

There are no binary packages available, but there is an alternative called “portsnap”. With portsnap you basically download a directory structure of all packages available. Go into the directory of the port you want, and execute the makefile in the directory to automatically download and install the port.

To install portsnap run:

portsnap fetch
portsnap extract
portsnap fetch
portsnap update

With portsnap I successfully compiled and installed the following programs:

  • screen
  • git
  • subversion
  • wget
  • autoconf
  • automake
  • libtool

References:

Wednesday, March 5, 2014

Restore/Setup Android project without IDE

Sometimes when the Android project directory is broken, you can restore the structure using the android executable in the Android "tools" directory.
android update project -p <path_to_project_directory> -n <project_name> -t <android_sdk_version>
You can also create a new project with:
android create project -p <path_to_project_directory> -n <project_name> -k <package_name> -a <activity_name> -t <android_sdk_version>
The android version parameter looks like this: "android-18".

Thursday, April 11, 2013

Package by features

A must-read about how to divide your Java application into packages that are modular and highly cohesive: http://www.javapractices.com/topic/TopicAction.do?Id=205

Thursday, February 7, 2013

Solution for jQuery plugin conflicts in Wicket

While I was working on a web application based on Wicket, I noticed that jQuery was not functioning in a way I expected. Using FireBug I noticed that a method call to a jQuery plugin failed, because it couldn't find the method. The HTML code I used in the <head>-element looks like this:

  <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
  <script type="text/javascript" src="js/jquery-plugin.js"></script>
  <script type="text/javascript">

    function callbackToPlugin() {
      return function () {
        $('#plugin').callToPlugin();
      };
    }

  </script>

The code-fragment includes the jQuery file and the custom plugin file. A function is defined below that returns a callback function that calls the plugin. The code in a Wicket web page class, decides if this callback is used or not. In the code below, the call is rendered in the <head>-element, when the boolean variable "callPlugin" is true.

  @Override
  public void renderHead(IHeaderResponse response) {
    if (callPlugin) {
      response.render(
        OnDomReadyHeaderItem.forScript("$(document).ready(callbackToPlugin())"));
    }
  }

The problem with this code is that Wicket includes its embedded jQuery file in the HTML output automatically, when it detects certain JavaScript function provided by Wicket is used. In this case it includes the jQuery file AFTER the definition of the callback function. What happens is that the definition of the plugin method "callToPlugin" is lost, because the second inclusion of jQuery resets the "$" jQuery variable. This will make our call fail.

The easiest solution I found is to assign another variable to jQuery using the "jQuery.noConflict()" function.

  <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
  <script type="text/javascript" src="js/jquery-plugin.js"></script>
  <script type="text/javascript">

    var $j = jQuery.noConflict();

    function callbackToPlugin() {
      return function () {
        $j('#plugin').callToPlugin();
      };
    }

    </script>

Now, the jQuery variable is "$j" instead of "$". Make sure you call the correct method from the Wicket page.

  @Override
  public void renderHead(IHeaderResponse response) {
    if (callPlugin) {
      response.render(
        OnDomReadyHeaderItem.forScript("$j(document).ready(callbackToPlugin())"));
    }
  }

If you have a better solution for this, please let me know in the comments.

Monday, November 5, 2012

Login twice in Wicket

Since the last time I upgraded my Wicket application, I noticed I had to login twice to be authenticated in the application. After careful research using the number one research tool (Google), I found the cause of this problem. The problem is that my login page is stateless. Wicket will create a temporary dummy session for stateless pages, which will not be saved internally in the session store. The solution is to let the session stick after authentication by calling bind in the session:
@Override
public boolean authenticate(String userName, String password) {
    // Your authentication code here...

    // Only reach this when authenticated...

    if (isTemporary()) {
        bind();
    }
}

Saturday, November 3, 2012

Reload JQuery when DOM is changed by Wicket/AJAX

I'm using many jQuery plugins in my Wicket application. When Wicket AjaxBehaviors change the DOM of the page, the initial changes made by the jQuery plugins are often lost. To solve this, we have to initiate the jQuery plugins again when the AjaxBehavior executes. We can do that by appending the plugin initialization JavaScript code like below:
aTextField.add(new OnChangeAjaxBehavior() {
    @Override
    protected void onUpdate(AjaxRequestTarget target) {
        target.add(aContainerThatIsRefreshed);
        target.appendJavaScript("$('.jQueryPluginClass').initiatePlugin();");
    }
});
Change the ".jQueryPluginClass" CSS class, and ".initiatePlugin()" plugin call for your specific project.

Saturday, August 4, 2012

Java Collection Matrix

Looking for a Java Collection class for your project, but don't know which one to use or is available? The link below will take you to a Java Collection Matrix, which lists the summarized properties of the standard Java Collection implementations.

http://www.janeve.me/articles/which-java-collection-to-use