Sunday, 11 October 2009

Bash Examples - Mistakes to Avoid

Bash Examples
A bash script is a text file containing a list of commands to be executed by the bash shell. A long time back, I had written a guide on Bash scripting which teaches you the basic syntax of bash scripts in a mere 10 seconds.
Read more »

Sun xVM VirtualBox v. 3.0.8 has been released

On October, 6th 2009 Sun Microsystems announced the release of a minor update to its flagship desktop virtualization solution, Sun xVM VirtualBox v. 3.0.8. As usual, you can check the changelog out at this address.

  • VMM: fixed 64 bits guest on 32 bits host regression in 3.0.6 (VT-x only; bug #4947)
  • VMM: fixed a recompiler triple fault guru meditation (VT-x & AMD-V only; bug #5058)
  • VMM: fixed hang after guest state restore (AMD-V, 32 bits Windows guest and IO-APIC enabled only; bug #5059)
  • VMM: fixed paging issue with OS/2 guests
  • VMM: fixed guru meditation in rare cases (2.0 regression; software virtualization only)
  • VMM: fixed release assertion during state restore when using the Sound Blaster 16 emulation (bug #5042)
  • Security: fixed vulnerability that allowed to execute commands with root privileges
  • Linux hosts: fixed runtime assertion in semaphore implementation which was triggered under certain conditions (bug #616)
  • Linux hosts: change the default USB access mode on certain distributions (bugs #3394 and #4291)
  • Linux hosts: on hardened Gentoo, the VBoxSVC daemon crashed by opening the VM network settings (bug #3732)
  • Linux hosts, Solaris hosts: pass the XAUTHORITY variable along
    the DISPLAY variable when starting a VM from VBoxManage or from the VM
    selector (bug #5063)
  • Linux hosts: use sysfs to enumerate host drives if hal is not available
  • Solaris hosts: fixed a bug which would hang the host sporadically as interrupts were not re-enabled everytime
  • Solaris hosts: fixed a kernel panic with bridged and host-only networking (bug #4775)
  • Solaris hosts: fixed incorrectly persistent CD/DVD-ROMs when changing them (bug #5077)
  • X11-based hosts: support additional function keys on Sun keyboards (bug #4907)
  • Mac OS X hosts (Snow Leopard): fixed problem starting headless VMs without a graphical session (bug #5002)
  • Mac OS X hosts: fixed problem listing host-only adapter names with trailing garbage (attached VMs won't start)
  • Windows Additions: now work with Vista 64-bit Home editions (bug #3865)
  • Windows Additions: fixed screen corruption with ZoomText Magnifier
  • Windows Additions: fixed NPGetUniversalName failure (bug #4853)
  • Windows Additions: fixed Windows NT regression (bug #4946)
  • Windows Additions: fixed VBoxService not running if no Shared Folders are installed
  • Linux Additions: implemented ftrunctate (bug #4771)
  • VRDP: start VM even if configured VRDP port is in use
  • Networking: the PCnet network device stopped receiving under rare conditions (bug #4870)
  • VBoxManage: implemented controlvm vrdpport command
  • iSCSI: fixed issue with NetApp targets (#5072)
  • SCSI: add support for virtual disks larger than 2TB
  • USB: fixed potential crash when unplugging USB2 devices (bug #5089)
  • NAT: IPSEC did not properly work with Linux guests (bug #4801)

Thursday, 8 October 2009

The iPhone as a gaming platform: the App. Store business model is the killer factor




I've been reading many articles about iPhone capabilities as a gaming platform: the last one I read, Wall Street Journal's Apple to Sony, Nintendo: Game Over man!, was quite clear.

Curiosity is a powerful driver and in a matter of minutes I found myself digging into the App. Store to choose a game to drive a quick test with. I chose Need For Speed Undercover. The quality of the game seems impressive to me. Rendering, music, responsiveness of the iPhone (it's a game whose user interface uses the built-in accelerometer): despite the size of the display, it seems like I'm running it with a last generation game console. No doubt. At the end of this articles Here are some NFSU screenshots, if you're wondering about its quality.

But the great news for me as an user, as Wall Street Journal pointed out, is not the fact that I'm handling a mobile device which, incidentally, is a great gaming platform too. This is just a technological accomplishment I could expect any other producer to achieve. The news is that I, who never owned a gaming console nor am planning to, bought a game. Let aside the initial investment to buy, for example, an XBox. Console games are traditionally priced at much higher a level than I paid for NFSU, yesterday. Moreover, you have to go and buy it. Even if you downloaded it, you should still need to burn it. Apple's App. Store model is the winner and killer here. Yesterday night I was laying in my bed with my iPhone, wondering whether I would keep on reading a book with Stanza. I thought about the WSJ article, I opened the App. Store, chose a game, clicked on it and... started to play! Right ahead, just after waiting just a couple of minute for the download to complete. I did not moved from there and was charged less than 4 Euros.

Game addicts may well say that the gaming experience is not nearly as equal as it is when using another platform. I have to agree, but that's out of topic. What strikes me most is the iPhone gaming experience as an end user, from the initial purchase. Easy, comfortable, handy, cheap! The App. Store, moreover, is a growing library of applications here at hand: sometimes, what's most difficult is not buying but choosing.










Developing Java EE applications for WebSphere AS with NetBeans

Chances are that if you're developing a Java EE application for IBM WebSphere Application Server, sometimes you'll need to use some IBM APIs to get the job done. If you're not using IBM's integrated development environment, you will have to add to your compilation classpath all the required libraries.

I'm a NetBeans fan and unless the customer explicitly prohibits this IDE, I always try to evangelize the developers working with me and switch to NetBeans. Lately, we've been developing a custom user registry and some login modules to plug into WebSphere Application Server: I definitely needed to link to WebSphere libraries.

To ease the switch to NetBeans from Rational Software Architect, I defined the library in my NetBeans and then distributed the definition of the NetBeans library, which simply is an XML file.

As you can see in this screenshot, the required libraries to work with WAS 6.1 are a good number and find themselves in a bunch of different WAS installation directories. In this case, I'm using the libraries of the WebSphere Application Server which is bundled with Rational Software Architect v. 7.0.

To distribute this definition to your fellow developers, you can just give them the library definition which you can find in the following directory (modulo NetBeans version number):

~/.netbeans/6.7/config/org-netbeans-api-project-libraries/Libraries

Since this library has been labeled WAS-6.1, the file name is WAS-6.1.xml.

The structure of such file is pretty intuitive, as you can see from this excerpt:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library PUBLIC "-//NetBeans//DTD Library Declaration 1.0//EN" "http://www.netbeans.org/dtds/library-declaration-1_0.dtd">
<library version="1.0">
    <name>WAS-6.1</name>
    <type>j2se</type>
    <volume>
        <type>classpath</type>
        <resource>jar:file:/C:/Archivos%20de%20programa/IBM/SDP70/runtimes/base_v61/lib/WMQ/java/lib/com.ibm.mq.jar!/</resource>
        <resource>jar:file:/C:/Archivos%20de%20programa/IBM/SDP70/runtimes/base_v61/lib/WMQ/java/lib/com.ibm.mqjms.jar!/</resource>
        <resource>jar:file:/C:/Archivos%20de%20programa/IBM/SDP70/runtimes/base_v61/lib/bootstrap.jar!/</resource>
        <resource>jar:file:/C:/Archivos%20de%20programa/IBM/SDP70/runtimes/base_v61/lib/j2ee.jar!/</resource>

Should you need it, you can process it with a program, or even with grep and sed, and batch-apply any change you'd need. For example, since my development platform of choice is Solaris whilst my client's is Windows, I frequently have to modify such files to adjust the library paths.

I'm now developing flawlessly in NetBeans and deploying our applications, or even our plugin modules, on WebSphere Application Server. NetBeans hasn't any plugin, as far as I know, to produce IBM-specific deployment descriptors but we're not experiencing any problems: we just apply deployment customization using WAS' excellent administration console.

Tuesday, 6 October 2009

Why I manually manage my iPhone's music

The problem

I own a pretty large music library which is hosted on a dedicated ZFS file system. Access to UNIX clients is provided via NFS and access to Windows clients is provided via CIFS. So far, so good. The problem is that the library is huge, very huge: not only the number of files is high, but some files themselves are huge. Whenever I buy a new CD, I rip it and encode it with a lossless codec in order to store the sufficient information in the case I need to burn another copy of the CD. On the Solaris Operating System, I'm using FLAC to encode such files. Alongside these lossless-encoded files, I use to encode another copy of the files in an easier to handle format, more suitable to use with portable devices. In this case, I use to re-encode FLAC files with an MP3 encoder.

Keeping organized such a library isn't difficult and the only problem I had so far is expanding storage according to my needs and backing it up: since I'm using ZFS, I'm an happier (and a wiser) man.

The problem with iTunes and such kind of programs is that they don't fit very well in the big library and networked storage scenario. Starting iTunes would take long to complete and, moreover, network would be the bottleneck. I never liked such a waste of resources and this is one of the reasons I never, ever, used a program to keep "organized" my music library.

But, what's the matter with the iPhone? Well, the iPhone is a glorified iPod and we all know that Apple is so kind to not allow us to read or write files on our phone but using iTunes.

iTunes synchronization

The iTunes way is very simple and idiot-proof: the iPhone is kept in sync with your iTunes-managed libraries: music, videos but also contacts, application and so forth. Kept I all of my music in just one laptop, that would (probably) be great but as I told you that's not (fortunately) the case.

The first times I synchronized my iPhone I used to:
  • Adding files to my library.
  • Synchronizing the iPhone.
Unfortunately, if my laptop cannot access the CIFS shares where the music is, iTunes just sees missing files and your iPhone will be empty after the next synchronization. Not so good.

The following times I thought I'd better copy files locally, first, and then synchronize. Good! Well, no. Because, unless you leave those files there (forever!), you'd hit the same behavior I described earlier. Replicating seldom is a good idea. Replicating such a library, definitely is not.

That's the kind of idiosyncrasy I hate in an end user program. Or it isn't an idiosyncrasy at all and it's me who's a strange user. Anyway, that's why I switched to manually manage my iPhone files. No library synchronization. I just copy files from the CIFS share directly into the iPhone. Just as if it was a plain old phone. No stale files on my laptop to keep iTunes happy.

Sunday, 4 October 2009

Google Wave Explained in Plain English

I was raring to try out Google Wave but havin't received an invite yet. So I did the next best thing which is to scrounge the Net for more info on Google Wave. Thus I chanced upon this wonderfully made video explaining in plain English what Google Wave is all about. Read more »

(Poor man's) Web redirection using a servlet filter

A couple of months ago I bought another domain because we're just in the middle of a re-branding and, obviously, the domain name was one of the first things to choose. We will keep the old domain in order to ease the migration of the systems we're running. Migrating the web was easy but, nowadays, there's some people who's resisting the re-branding process and who's still using our old name and our old domain.

After consulting the company that hosts our old domain, they answered this: 2.5 Eur/Month for web and email redirection. Since we don't need mail redirection, paying a couple of bucks just to send a couple of HTTP headers seemed much to me, that's why I decided to do it myself.

Setting up Sun Java System Application Server on Solaris 10

First of all, I set up a new sparse and shared-IP zone. At the end of the installation I checked the startup script for the Sun Java System Application Server that ships with Solaris 10. If you need a Java application server, you'd better go and install the latest version. As I'm going to run just one servlet filter, using the bundled server seemed like fine to me.

The bundled server is installed in /usr/appserver and isn't either SMF-managed:

$ svcs S84appserv
STATE          STIME    FMRI
legacy_run     Mar_13   lrc:/etc/rc3_d/S84appserv


If you examine the startup script, you'll notice that it looks for domains installed in the /var/appserver/domains directory. Of such domains, this scripts starts those who configured the autostart feature, which is simply an empty file named [domain-dir]/config/autostart.

Creating a domain

To create a domain you need to use the /usr/sbin/asadmin command. In my case, I used the following command:

/usr/sbin/asadmin create-domain --domaindir /var/appserver/domains --adminport 4848 --adminuser admin --instanceport 8080 --savemasterpassword=true my-web

  • --domaindir /var/appserver/domains is necessary to create the domain in the directory searched by the legacy startup script.
  • --adminport and --instanceport are used to configure the ports used respectively by the admin console and the applications you'll deploy in this domain.
  • --savemasterpassword, or an equivalent technique, is necessary because the startup script is non interactive and cannot ask you about the master password.

Once the domain was done, I touched the autostart file to trigger the startup of the domain:

$ touch /var/appserver/domains/my-web/config/autostart

You can now start your domain by using the startup script:

# /etc/rc3.d/S84appserv start

To test your installation you can use your favorite browser to connect to the admin console on the port you specified (in this case, 4848) or to view the welcome file (on port 8080).

Creating a redirecting servlet filter

To redirect clients' HTTP requests to the new domains we just need to send a HTTP 301 status code (moved permanently) and the new location in the Location HTTP header. Omitting the boiler plate code of a standard Java Servlet filter, the code is just a two liners:

response.setHeader("Location", "http://www.newdomain.es/");
response.setStatus(response.SC_MOVED_PERMANENTLY);

Please note that the setHeader and the setStatus method aren't methods of the ServletResponse class: they're included into the HttpServletResponse class.

The last thing to do is mapping the filter in the web module deployment descriptor:

$ cat WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <filter>
        <filter-name>RedirFilter</filter-name>
        <filter-class>es.reacts.filters.RedirFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RedirFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

The application server bundled with Solaris 10 will complain with an not so intuitive "Unsupported minor.major 49.0 error" if you don't compile your application with a Java 1.4 compiler. Once this was done, you just have to deploy the web module into your server in the root (/) context path.


Setting up the network

The last part of the job was setting up the network. First of all, I removed the DNS A record identifying the www machine (which pointed to our hosting company web server) and substituted with a CNAME pointing to the machine of ours where I deployed the Java web module and then I configured our border router to map port 80 to the port where the Sun Java System Application Server is listening.

Manipulating URIs before redirecting

The filter described so far redirects a request to the root of an application to another URL. The basic problem with this example is that, if a client requests an URI beneath the root of an application, unless such URI is mapped to a valid resource into the application, the application server will return an HTTP 404 status code (not found). The filter semantics is such, indeed: they're executed before the request is handled by its target and, if it does not exist, they're not triggered at all.

To avoid such problems, if you want a catch-all redirection, or if you prefer to process the request before redirecting it, you can deploy a servlet and map it to the URIs you want to catch. And if you want to catch them all, mapping /* is all you need.

The final version of the web.xml of the web module I deployed is the following:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    <filter>
        <filter-name>RedirFilter</filter-name>
        <filter-class>es.reacts.filters.RedirFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RedirFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>Default</servlet-name>
        <servlet-class>es.reacts.servlets.Default</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Default</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

A Virtual Hosts based solution

As I described in another post, if you're an Apache HTTP Server user, there's an out-of-the-box, more flexible and easier solution: Virtual Hosts.