Monday, December 21, 2009

iPhone on a Solaris Host

I'm a moderately happy owner of an iPhone and, as I'm usually running Solaris on my systems, I've struggled to find a working solution to connect my handset to an iTunes instance. One of the major drawbacks of the iPhone is that you really need iTunes: whether you want to upgrade it, back it up, or simply transfer the contents you purchased on the Apple stores, you need iTunes to get the job done.

I'm running several virtualized OS on my Solaris guests with Sun xVM VirtualBox, and never managed to make it work because of some limitations of the Solaris USB driver implementation. A couple of days ago, Sun announced the release of xVM VirtualBox 3.1.2 and in the changelog I read the following:
  • Solaris hosts: several USB fixes (including support for Apple iPhone)

I quickly updated my VirtualBox instance, quickly live-upgraded my Solaris Express Nevada build 116 to Nevada build 129 (during the installation, VirtualBox informed me that it needed recent Nevada builds for the USB kernel module to work properly), plugged the iPhone in an USB slot of a Sun Ultra 24 and it worked!





Sun xVM VirtualBox v. 3.1.2 has been released

Sun xVM VirtualBox v. 3.1.2 has been released. This is a minor update and the current changelog is:
  • VMM: fixed SMP stability regression
  • USB: fixed USB related host crashes on 64 bits Windows hosts (#5237)
  • Main: wrong default HWVirtExExclusive value for new VMs (bug #5664)
  • Main: DVD passthrough setting was lost (bug #5681)
  • VBoxManage: iSCSI disks do not support adding a comment (bug #4460)
  • VBoxManage: added missing --cpus and --memory options to OVF --import
  • GUI: fixed VBox URL in update dialog for German and Dutch languages
  • GUI: NLS updates
  • OVF: fixed export of non standard storage controller names (bug #5643)
  • Solaris hosts: several USB fixes (including support for Apple iPhone)
  • Mac OS X hosts: several fixes for the 3D support
  • Mac OS X hosts: re-enabled CMD+Key combinations, even if the Host-Key isn't CMD (bug #5684)
  • Mac OS X hosts: fixed to fast scrolling if the mouse wheel is used inside the guest (bug #5672)
  • Mac OS X hosts: dock & menubar don't disappear in fullscreen when the VM is not running on the primary display (bug #1762)
  • Mac OS X hosts: added an option for enabling "Auto show Dock & Menubar in fullscreen" (bug #5636)
  • Windows host installer: fixed starting VBox with wrong privileges right after installation (bug #4162)
  • Host interface and host-only networking: prevent driver from unloading while a VM is still active (Windows host only)
  • Host-only networking: fixed host-only interface creation (Windows host only) (bug #5708)
  • Virtio-net: don't crash without an attached network
  • Virtio-net: fixed the issue with intermittent network in VM with several virtual CPU cores.
  • NAT: fixed port-forwarding regressions (bug #5666)
  • NAT: fixed crash under certain conditions (bug #5427)
  • NAT: fixed resolving of names containing a slash or underscore when using the host resolver DNS proxy (bug #5698)
  • ATA: fixed sporadic crash when resuming after a VM was forcefully paused (e.g. due to iSCSI target being unavailable)
  • SATA: fixed raw vmdk disks (bug #5724)
  • Linux guests: increased the default memory for Redhat and Fedora guests
  • Linux Guest Additions: fixed installation on RHEL 3.9 guests and on some 64bit guests
  • Linux Guest Additions: prevent SELinux warnings concerning text relocations in VBoxOGL.so (bug #5690)
  • X11 guests: fixed mouse support for some Xorg 1.4 guests (openSUSE 11.0)
  • X11 guests: fixed xorg.conf modification for some older Xorg releases (openSUSE 11.1)
  • Windows guests: fixed some VBoxService shutdown issues
  • Windows guests: fixed VBoxVideo spinlock issues on NT4
  • Windows Guest Additions: fixed uninstallation issues of NT4
  • Shared folders: fixed resolving of symlink target (bug #5631)
  • 2D Video acceleration: delay loading of OpenGL dlls for Windows hosts to avoid GUI crashes on misconfigured systems
  • 2D Video acceleration: fixed issues with video picture not displayed on playback

The changelog claims that support for Apple iPhone has been included for Solaris hosts. If working, that's what I'd been waiting for months!

Tuesday, December 15, 2009

Java Enterprise Edition 6 has been released

The specification for Java Enterprise Edition v. 6 has been released. This major upgrade introduces many new features to ease Web and Enterprise applications development. The list of the technologies included in this release can be view here. Besides upgrades to veteran specifications such as Servlet, JSP and EJB, the Java EE platform introduces:
  • Java API for RESTful Web Services: an annotation-based API to easily convert a POJO and publish its logic as a RESTful web service.
  • Managed Beans 1.0: Java EE containers can now manage ordinary Java classes with few (or no) restrictions (POJOs). Managed bean support lifecycle events, injection and interceptors. Other specification are, such as Web Beans), are built upon managed beans.
  • Contexts and Dependency Injection for Java (Web Beans 1.0): The CDI specification, built upon managed beans, provides the well-known JBoss Seam's Web Beans functionality to the Java EE platform: a sophisticated context and dependency injection model.
  • Bean Validation: An annotation-based API to declare validation constraints on a POJO and a validation API to programmatically validate bean instances.

If you want to start and try this new platform, download the Java EE SDK or download NetBeans, whose version 6.8 integrates Java EE 6 support and Glassfish Enterprise Server 3.0.



Tuesday, December 1, 2009

Selecting the locale for an user with JSTL

In another post, I introduced the basic internationalization capabilities built in JSTL. The algorithm used to choose a suitable locale for an user is a good default choice: without any effort, your web application will show up in the correct locale.

But what if you wanted to let the user choose the locale?

Well, the JSTL Specification lets you establish a locale and a scope: such as page, request, session, application. The first sketch I'd come up with would be something like creating a servlet to enforce the programmatic configuration.

Language selector servlet

This is a servlet service method prototype:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    final String lang = request.getParameter("lang");
    if (isSupported(lang)) {
        Config.set(request.getSession(), Config.FMT_LOCALE, lang);
    }

    request.getRequestDispatcher("/").forward(request, response);
}

The important call here is Config.set(...): you're telling JSTL to use the specified locale (as a String) and save it in the session scope. This servlet accepts the lang parameter and, if present, uses it to determine if it represents a supported locale (isSupported implementation is omitted). If it is, it uses it as described above. At the end of it all, forwards the user at the web welcome page (if any).

Refinements

The servlet described above is the first step towards a complete user customization and is just an example of how you can use the JSTL's Config class. Desirable improvements might be:
  • Saving the user servlet in its profile (if the user has been authenticated) so that future sessions will automatically use the user-specified locale.
  • Using a servlet filter instead of a servlet to automatically intercept the lang parameter and leave the web navigation unaffected.





Internationalization using JSTL

The Java EE 5 platform is a powerful enterprise-level server development platform which in my opinion is very productive including to develop small web modules, provided you've got a suitable Application Server or Servlet Container to run it.

As far as it concerns web development and authoring, Java EE 5 has got some great APIs such as servlet's, JSP's and JSF's. The JavaServer Pages Specification (JSR 245) includes JSTL (JavaServer Pages Standard Tag Library, JSR 052), which are JSP standard tag extensions that include internationalization features.

Creating a Resource Bundle

The first thing you ought to do when internationalizing your application is creating resource bundles. Resource bundles are Java Properties file, organized for locales, whose aim is separating string literal according to the locale they're meant for.

Let's suppose you want to use three locales in your application:
  • en_US
  • it_IT
  • es_ES

Create for Java Properties files, one per locale and one as a fallback. The naming scheme is [bundle-name]_[locale].properties, so that you'll end up with:

bundle_en_US.properties
bundle_it_IT.properties
bundle_es_ES.properties

Some advances Java IDE, such as NetBeans, let you manage properties files with visual tools and perform basic operations, such as adding a locale or filling up the properties, with a fancy GUI.

Filling the Resource Bundles Up

Filling up properties files is pretty easy: such files contain records with this basic structure:

key=value

In this case you would translate every key value for the correct locale.

Using a Bundle from a JavaServer Page with a JSTL tag

JSTL lets you easily use resource bundles in a JSP. The first thing you've got to do is declaring that you're going to use the JSTL's fmt tag library:

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

The next thing is telling the library which bundle you're going to use. Let's suppose you're going to use com.domain.YourBundle:

<fmt:setBundle basename="com.domain.YourBundle" />

The last thing is using the retrieved values where you need them:

<fmt:message key="your.key" />

Determining the user locale

Maybe you're wondering how JSTL determines which is the user locale. JSTL, by default, determines the user locale by examining the headers sent by the browser and applying a best match algorithm. If your preferred language settings show (in this order)
  1. English
  2. Spanish
  3. Italian

the resulting application will show up in English. The JSTL Specification will give you further details about how to establish a default locale for a web application using JSTL.

In another post, I'll show you how I resolved the problem of locale switching for a given user in an application of ours.

Further Readings




Sun xVM VirtualBox v. 3.1.0 has been released

Sun xVM VirtualBox v. 3.1.0 has been released. This is a major update which introduces some brand-new great features such as (change log excerpt):
  • Teleportation (aka live migration); migrate a live VM session from one host to another (see the manual for more information)
  • VM states can now be restored from arbitrary snapshots instead of only the last one, and new snapshots can be taken from other snapshots as well ("branched snapshots"; see the manual for more information)
  • 2D video acceleration for Windows guests; use the host video hardware for overlay stretching and color conversion (see the manual for more information)
  • More flexible storage attachments: CD/DVD drives can be attached to an arbitrary IDE controller, and there can be more than one such drive (the manual for more information)
  • The network attachment type can be changed while a VM is running
  • Complete rewrite of experimental USB support for OpenSolaris hosts making use of the latest USB enhancements in Solaris Nevada 124 and higher
  • Significant performance improvements for PAE and AMD64 guests (VT-x and AMD-V only; normal (non-nested) paging)
  • Experimental support for EFI (Extensible Firmware Interface; see the manual for more information)
  • Support for paravirtualized network adapters (virtio-net; see the manual for more information)

As far as it concerns myself, teleportation is the feature I was looking forward. Great job, guys.

Read the changelog.
Download Sun xVM VirtualBox now.


Thursday, November 26, 2009

Retrieving a server public SSL key on Solaris 10 (such as GMail's)

This is a tip for you, UNIX users (with OpenSSL installed), who wish to obtain a server's public SSL key.

I'm configuring a Java EE application that needs to connect to an IMAP server using SSL on a Solaris 10 box. For that reason, I need to import the IMAP server SSL public key into my Java runtime certificates file.

Solaris 10 brings a bundled OpenSSL package which it's very easy to accomplish this task with. Just launch your favorite shell and execute the following command:
$ openssl s_client -connect destination.server:[service|port]

In my case, being an IMAP server using a non-standard port, I used:

$ openssl s_client -connect my.imap.server:999
CONNECTED(00000004)
[...snip...]
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDWzCCAsSgAwIBAgIKYgnCCAADAAAJ5DANBgkqhkiG9w0BAQUFADBGMQswCQYD
VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu
dGVybmV0IEF1dGhvcml0eTAeFw0wOTA3MTcxNzEzNDFaFw0xMDA3MTcxNzIzNDFa
MGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N
b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRcwFQYDVQQDEw5pbWFw
LmdtYWlsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA+O0vc2pslfjk
pbxnBF4iznJMrP9Qi3fHjKqA3P2RynTcbnZfGEGMKcPeXHT4IOH6XUnf+4Jw+z7I
KiMtjX8IVGo7DeXec/ZREasEZnpMGisxN7+qk7Ho6HyaglQTAFIQJP99UFJkHO9x
dGDy5d2j9senPad1BqtyaIRGkJpHizUCAwEAAaOCASwwggEoMB0GA1UdDgQWBBT0
WHOeLKf4+VNADzHzGh+AEV+6fjAfBgNVHSMEGDAWgBS/wDDr9UMRPme6npH7/Gra
42sSJDBbBgNVHR8EVDBSMFCgTqBMhkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dv
b2dsZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNy
bDBmBggrBgEFBQcBAQRaMFgwVgYIKwYBBQUHMAKGSmh0dHA6Ly93d3cuZ3N0YXRp
Yy5jb20vR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkvR29vZ2xlSW50ZXJuZXRBdXRo
b3JpdHkuY3J0MCEGCSsGAQQBgjcUAgQUHhIAVwBlAGIAUwBlAHIAdgBlAHIwDQYJ
KoZIhvcNAQEFBQADgYEAXLvdKJJ6ivWAi29p4pPo4cirMEYnRlpNOmPVAW4QYcSq
lEZhm4cQdyitFo9cxiwNgbBjJk8O+oiOhnueT44RXotEE7j3KnNyPRRZg0OCagGC
4G71fFA11P1L0fSd/7k52/DbZQBea3tJgkseoGL50UVvnJm+LZOovIGxoQzipJk=
-----END CERTIFICATE-----
[...snip...]

The key I need to import is the shown certificate, including the beginning and the end line.

I saved the key in a file called imap.key and I imported in my Java runtime certificates file with the following command:

$ /usr/jdk/latest/bin/keytool -import -alias imap.gmail.com -keystore /usr/jdk/latest/jre/lib/security/cacerts -file imap.key
[Insert password here]
[Confirm key import]

Done!
Now, my Java application can use that public key to establish a secure SSL connection with the target imap host.

Tuesday, November 24, 2009

Protecting workflow transitions in JIRA

Today I created a bunch of new projects in our JIRA 4.0 instance and, for the first time, I needed to create a custom workflow for some issue types. JIRA is flexible and powerful and it was pretty easy to create a new workflow just cloning (copying) the default JIRA workflow. All I had to do to fulfill my requirements was:
  • Define a new status: Waiting for feedback
  • Define a new step: Waiting for feedback
  • Create new transitions to and from this new workflow state.

Leveraging JIRA's powerful administration console the new workflow was defined in just a few minutes. Once done, I defined a new workflow scheme and associated to some of my new projects.

It was with some surprise that I realized that the new transition wasn't restricted to developers: it was there for everyone to trigger. Obviously, I'd overlooked something in the configuration so that I checked the permissions and everything seemed to be fine until I realized what was wrong: workflow transitions are protected by conditions. In my case, I required that only the issue assignee could trigger a transition.

Although the workflow was being used, creating a draft workflow was a no brainer. In the draft workflow I added the required condition:
Only the assignee of the issue can execute this transition.

Once done, I published the new workflow. JIRA quickly converted the existing issue to the new workflow and the error was corrected without even bringing the project down.

Sunday, November 22, 2009

Configuring Sendmail to Relay Messages from Other Servers

Index




Part 1. Configuring Sendmail on Solaris 10
Part 2. Configuring Sendmail to Masquerade Your Messages
Part 3. Configuring Sendmail to Relay Messages to Another Server
Part 4. Configuring Sendmail to Relay Messages from Other Servers

Introduction

In the previous post you've learnt how to configure Sendmail to relay messages to another server. Now, such a server should be probably be configured to accept incoming messages to relay from other servers. Solaris 10 Sendmail default configuration does not allow message relay and proper configuration must be applied to Sendmail.

Configuring Relay for Hosts and Domains

The quickest way to have Sendmail relay messages for other domains is by modifying the /etc/mail/relay-domains file. Sendmail will relay mail for every domain listed in that file. If you want your server to relay messages for domain a.com, b.com and c.com, just insert the corresponding lines into /etc/mail/relay-domains and restart your Senmail instance:

# cat /etc/mail/relay-domains
a.com
b.com
c.com

Configuring the Access Database

If you want to relay messages from specific hosts (as well as domains and networks) you can use the access database. The access database lists email addresses, network numbers and domain names and a rule. Available rules are:
  • OK: Accept mail even if other rules in the running ruleset would reject it.
  • RELAY: Accept mail addressed to the indicated domain or received from the indicated
    domain for relaying.
  • REJECT: Reject the sender or recipient with a general purpose message.
  • DISCARD: Discard the message completely using the $#discard mailer.
  • (A RFC-821 compliant error text): Return the error message.

If you want your Sendmail to relay mails for a domain or from some specific hosts, modify your /etc/mail/access accordingly:
your-domain       RELAY
192.168.0         RELAY
another-domain    RELAY
unwanted-host     REJECT

Once done, you have to generate the access db with the following command:

# makemap hash /etc/mail/access.db < /etc/mail/access

Enabling the Access Database

To have your Sendmail use the access database, you must properly configure it adding the access_db feature to its configuration file:

# cat your-file.mc
[...snip...]
FEATURE(`access_db')
[...snip...]

Restart your Sendmail and enjoy!

A Word of Warning: DNS Configuration

Sendmail often requires that host name you use in your configuration files (such as the access database) are properly configured in your name server, both for lookup and reverse lookup. I hope this will spare you some headache while debugging.

Configuring Sendmail to Relay Messages to Another Server

Index




Part 1. Configuring Sendmail on Solaris 10
Part 2. Configuring Sendmail to Masquerade Your Messages
Part 3. Configuring Sendmail to Relay Messages to Another Server
Part 4. Configuring Sendmail to Relay Messages from Other Servers

Introduction

Sometimes you just need to configure your Sendmail to relay messages to another server. I often use such a configuration to centralize Sendmail configuration: if something had to change I would just need to change a reduced number of configuration files. For example, I made heavy use of Solaris Zones technology. Unless particular configuration is needed, whenever I create a new zone, I just configure its Sendmail to relay messages to another server (which is, incidentally, one of the preconfigured Sendmail zones we use).

Setting Up a Sendmail Smart Host

Setting up Sendmail to relay messages to another server is pretty easy. Modify your configuration file and use the following macro:

[...snip...]
define(`SMART_HOST', `your-smart-host')

[...snip...]

The smart host is the host this instance will relay messages to. This macro will be translated into a DS statement in your Sendmail configuration file. You should never modify .cf files directly: always compile .mc files! By the way, sometimes is useful to know .cf syntax if you need to interpret existing .cf files when you've lost the corresponding .mc files (something that should never pass to a seasoned System Administrator).

Configuring Sendmail to Masquerade Your Messages

Index


Part 1. Configuring Sendmail on Solaris 10
Part 2. Configuring Sendmail to Masquerade Your Messages
Part 3. Configuring Sendmail to Relay Messages to Another Server
Part 4. Configuring Sendmail to Relay Messages from Other Servers

Sendmail Masquerading

Now that you've got your Sendmail up and running it's time to do some tweaking. If you try and send mail from your host, you'll notice that messages are sent from an address such as your-user-name@hostname.your.domain. That's not probably what you want (that address isn't probably even reachable from the outside) and you'd rather like: your-user-name@your.domain. Fine, that feature is called masquerading. To masquerade outgoing mail you can use the MASQUERADE_AS and MASQUERADE_DOMAIN macros, as in the following example:

divert(0)dnl
VERSIONID(`@(#)sendmail.mc      1.11 (Sun) 06/21/04')
OSTYPE(`solaris8')dnl
DOMAIN(`solaris-generic')dnl
define(`confFALLBACK_SMARTHOST', `mailhost$?m.$m$.')dnl
MASQUERADE_AS(`your-domain.com')dnl
FEATURE(`masquerade_envelope')dnl
FEATURE(`masquerade_entire_domain')dnl
FEATURE(`always_add_domain')dnl
MASQUERADE_DOMAIN(`your-domain.com')dnl
MAILER(`local')dnl
MAILER(`smtp')dnl

LOCAL_NET_CONFIG
R$* < @ $* .$m. > $*    $#esmtp $@ $2.$m $: $1 < @ $2.$m. > $3

Restart your sendmail and the job is done.

Configuring Sendmail on Solaris 10

Index



Part 1. Configuring Sendmail on Solaris 10
Part 2. Configuring Sendmail to Masquerade Your Messages
Part 3. Configuring Sendmail to Relay Messages to Another Server
Part 4. Configuring Sendmail to Relay Messages from Other Servers

Introduction

Whoever tried to get Sendmail up and running will agree that taming Sendmail requires black magic. I won't even try to enter into Sendmail internal and details: I don't master it and conform with being able to configure my Solaris box (and zones) to fulfill my needs. Nevertheless, I'll admit that Sendmail has got its own spell and felt compelled to keep on reading on to discover what Sendmail is capable of.

Verifying Sendmail State and Starting It Up

Solaris 10 Sendmail is configured as an SMF-managed service. To check sendmail status you can use:

$ svcs \*sendmail\*
STATE          STIME    FMRI
online         14:19:23 svc:/network/smtp:sendmail

If Sendmail were not enabled, just use svcadm to bring it up:

# svcadm enable svc:/network/smtp:sendmail

Configuring Sendmail for Open Mode

Solaris 10 Sendmail configuration is such that Sendmail will only run in local mode, thus rejecting connections from other hosts. If you want to review Sendmail default Solaris 10 configuration, you can use:

# svccfg -s svc:/network/smtp:sendmail listprop
[...snip...]
config/local_only                    boolean  true
[...snip...]

If you're curios, SMF properties are used by SFM methods. A closer examination to Sendmail startup script in Solaris 10, indeed, reveals the following:

    local=`/usr/bin/svcprop -p config/local_only $SMF_FMRI 2>/dev/null`
    if [ $? = 0 -a "$local" = "true" ]; then
        OPTIONS="$OPTIONS -C /etc/mail/local.cf"
    fi

If you want to configure your Sendmail to work in open mode you can run the following:

# svccfg -s svc:/network/smtp:sendmail setprop config/local_only= boolean: false
# svcadm restart svc:/network/smtp:sendmail

Solaris 10 Default configuration

If you inspect the default sendmail.mc file for Solaris 10 you'll find the following:

divert(0)dnl
VERSIONID(`@(#)sendmail.mc      1.11 (Sun) 06/21/04')
OSTYPE(`solaris8')dnl
DOMAIN(`solaris-generic')dnl
define(`confFALLBACK_SMARTHOST', `mailhost$?m.$m$.')dnl
MAILER(`local')dnl
MAILER(`smtp')dnl

LOCAL_NET_CONFIG
R$* < @ $* .$m. > $*    $#esmtp $@ $2.$m $: $1 < @ $2.$m. > $3

Local and smtp mailers are on and you should be able to send mail, both locally and remotely, from such a host. Unless you configure your perform additional configuration, you won't be able to connect remotely to this instance, nor using such an instance as a mail relay. Naturally, some tweaking is usually required and it will be performed with the procedure described in the following sections.

Building a Configuration File for Sendmail

To build a configuration file for your Sendmail you can perform the following:
  • Temporarily disable your Sendmail:

# svcadm disable -t svc:/network/smtp:sendmail

  • Go to Sendmail configuration templates directory:

# cd /etc/mail/cf/cf


  • Start with a fresh file and write your configuration down:

# cp sendmail.mc your-file.mc

Compile your file:

# /usr/ccs/bin/make your-file.cf

Test your configuration:

# sendmail -C your-file.cf -v your-email-address </dev/null

Apply your configuration:

# cp your-file.cf /etc/mail/sendmail.cf

Restart and use Sendmail:

# svcadm enable svc:/network/smtp:sendmail

A good place to start for studying Solaris 10 Sendmail is Solaris System Administration Guide: Network Services (Chapter 13).




Thursday, November 19, 2009

Web Technologies on a Desktop Application - Portability Do Matter

What's the desktop application most commonly used? For a great majority of persons the answer is simple: the browser. The omnipresent browser has begun not to be perceived as an application anymore: instead, it's the container where web applications run.




Although there's still plenty of space for desktop applications,
they can't be thought as stand-alone any longer. Users continuously
rely on Internet as a source of information and desktop applications had to learn to use Internet as if it were a database.




Browsers and web developers probably learnt that before: Web
Services and the AJAX paradigm being just the last trends in the
industry. Vendors have been implementing similar technologies in their
SDKs and the boundary between web-technologies and general purpose
framework gets thinner day by day.



I just remember when JAX-* specifications were being integrated into
Java2 Enterprise Edition: nowadays you can hardly think of a Java
desktop application not leveraging JAX-WS or JAX-RS.




Many vendors have being trying to port web technologies on the desktop and the major players in this are are:


  • Adobe, with Adobe AIR
  • Sun Microsystems with JavaFX framework
  • Google, with Google Gears




I've being intensively using Gears-powered applications just because
I'm a faithful Google applications user. I must say that I'm pretty
happy with it and that in this sense Google is probably making one step
more in this direction with its Google Chrome OS. Nowadays, although
Google Chrome still is a browser, it really acts as an environment for Google Gears applications.




As far as it concerns JavaFX, I've played a little with it with my
NetBeans and I must say that I'm impressed. Java SE and Java EE already
have all of the pieces you need to build rich internet applications and
JavaFX goes one step further: it's a platform that aims to support a
variety of devices (browsers, mobile phones, gaming consoles and so
forth).



Adobe AIR is impressive: although I never wrote any line of of code, I've seen some applications and, just as anything-Adobe, great hype is given to integration with Flex/Flash applications.




Which one should I go with?



Although every framework has got its own peculiar advantages, such a
decision depends on many factors, such as your needs and your
requirements.



One of the fundamental advantages of web applications is their
platform-independence (usually). Yes, there are many glitches depending
on the browser you're using but nowadays the situation is pretty
satisfactory, at least as far as it concerns an application
functionality. Such an independence is achieved by means of the
browser, which is the container in which such an application is
executed. Taking an application out of the browser is complex and in
that process you run the risk of reducing an application's portability.
That's the original sin of many frameworks, such as Adobe AIR.




I strongly believe in portability and that's something I'm
never going to sacrifice easily and when I do the requirement must be
compelling. That's why I always go with Java.



Let alone enterprise-level technologies supported by Java Enterprise Edition, Java gives you the basic tools you need such as:


  • A powerful programming language.
  • Support for Web Services (JAX-RPC and JAX-WS).
  • Support for RESTful Web Services (JAX-RS)
  • Support for AJAX.
  • Integration with databases (JDBC, JPA)




The Java language itself has been recently enhanced by annotations
which are commonly used by specifications and frameworks (such as
Spring) to greatly reduce boilerplate code. EJB 3.0, JPA, JAX-RS,
JavaBeans Validation (JSR-303) are just examples of the
annotation-centric APIs you can use in a Java program just by applying
metadata to your class and letting the framework (or the container) do
the job. POJO-based and annotation based frameworks and APIs greatly
contributed to simplify the programming models previously used: whether
you're developing a web service, a web service client, an interaction
with a DB, an EJB, you're probably producing just POJOs. Reusing such
objects is straightforward: the boundary that existed between the
various kind of Java applications have blurred and nowadays is almost
null.



Moreover, in the incredibly vast ecosystem of Java libraries and
frameworks you're probably going to find everything you need to get the
job done.




Conclusion



When deciding the tools you're going to use to develop your next
application, always consider that there's someone out there who might
not be using your browser or your OS. If you haven't got compelling
reasons, don't shut the door in their face. Users do not understand, sometimes not even with reasons. And they'd just turn to another provider.


Tuesday, November 17, 2009

Apache HTTP Server Virtual Hosts (on Solaris)

Some posts ago (Poor man's web redirection using a servlet filter) I described how I'm sending an HTTP Redirect Status Code back to a client. Such a solution was easy for me to implement because we're already running Java EE applications on our application servers and, on the other hand, we have no other web server available (if you're thinking about Apache HTTP Server). The previous post fails in pointing out that, implementing such a solution from scratch, is really overkill.

If you're one of the many users of Apache HTTP Server you should be aware of a functionality called Virtual Hosts. Virtual hosts let you run multiple web sites on a single Apache HTTP server instance and requests will be forwarded to the appropriate web site by using either the target IP address or the name you used to connect to the site. The last step will be configuring Apache so that such a Virtual Host will be served by proxying the destination server.

With such a proxy/gateway you'll be able, for example:
  • To serve different domains, subdomains or even specific URLs with just one Apache HTTP Server instance.
  • To offer a gateway in the case you've got a reduced number of public IPs and you don't want to publish HTTP services on ports other than 80.

DNS configuration

First of all I substituted the old DNS record with a CNAME which points to this Apache HTTP Server instance. Now, whenever a client requests www.domainA.com, the connection will be established with the target Apache.

Apache HTTP Server Startup

On (Open)Solaris, check if you've got an Apache HTTP Server instance running:
# svcs \*apache\*
STATE          STIME    FMRI
legacy_run     Mar_13   lrc:/etc/rc3_d/S50apache
disabled       Mar_13   svc:/network/http:apache2

If it isn't running, create a suitable configuration file in /etc/apache2:
# cp httpd.conf-example httpd.conf

Once the configuration file is created, the service should start normally:
# svcadm enable svc:/network/http:apache2
# svcs http:apache2
STATE          STIME    FMRI
online         Nov_15   svc:/network/http:apache2

Apache HTTP Server Configuration

The last thing to do is creating virtual hosts:

NameVirtualHost *

<VirtualHost *>
ServerName domainA.com
DocumentRoot /var/apache2/htdocs
</VirtualHost>

<VirtualHost *>
ServerName subdomain.domainA.es
ProxyPreserveHost On
ProxyPass / http://localhost:8083/
ProxyPassReverse / http://localhost:8083/
</VirtualHost>

In the previous fragment you can notice the following:
  • the NameVirtualHost directive lets you configure Apache to listen on a specific address and port. In this case, any IP address and any port (*) have been configured.
  • The VirtualHost sections let you define virtual hosts. Please note that the NameVirtualHost value and the VirtualHost value must be the same (in this case, *).
  • The ServerName directive is used to assign the domain name a virtual host should serve.
  • ProxyPreserveHost is used to tell Apache not to override the Host HTTP header when connecting to the proxied host.
  • ProxyPass and ProxyPassReverse lets you map proxied URL spaces. In this case, everything (/) is sent to the proxied host (http://localhost:8083/).

Further Readings
If you want to go into deeper detail, please read the following:


Sun xVM VirtualBox 3.0.12 has been released

On November, 17th, Sun has announced the release of Sun xVM VirtualBox 3.0.12. The changelog for this release is the following:
  • VMM: reduced IO-APIC overhead for 32 bits Windows NT/2000/XP/2003 guests; requires 64 bits support (VT-x only; bug #4392)
  • VMM: fixed double timer interrupt delivery on old Linux kernels using IO-APIC (caused guest time to run at double speed; bug #3135)
  • VMM: reinitialize VT-x and AMD-V after host suspend or hibernate; some BIOSes forget this (Windows hosts only; bug #5421)
  • VMM: fix loading of saved state when RAM preallocation is enabled
  • BIOS: ignore unknown shutdown codes instead of causing a guru meditation (bug #5389)
  • GUI: never start a VM on a single click into the selector window (bug #2676)
  • Serial: reduce the probability of lost bytes if the host end is connected to a raw file
  • VMDK: fix handling of split image variants and fix a 3.0.10 regression (bug #5355)
  • VRDP: fixed occasional VRDP server crash
  • Network: even if the virtual network cable was disconnected, some guests were able to send / receive packets (E1000; bug #5366)
  • Network: even if the virtual network cable was disconnected,
    the PCNet card received some spurious packets which might confuse the
    guest (bug #4496)
  • Shared folders: fixed changing case of file names (bug #2520)
  • Windows Additions: fix crash in seamless mode (contributed by Huihong Luo)
  • Linux Additions: fix writing to files opened in O_APPEND mode (bug #3805)
  • Solaris Additions: fix regression in guest additions driver
    which among other things caused lost guest property updates and
    periodic error messages being written to the system log

If you want to update or if you want to give VirtualBox a test drive, download it now.

Friday, November 13, 2009

Fluendo DVD Player for Solaris has finally been released


Many of us Solaris users have been waiting for this a long time. Fluendo has finally released its DVD Player for Solaris as well.

This is great news. I've been using Fluendo codecs on Solaris since a long time and I'm trying right now their DVD Player. So far I had no issue and it clearly is a leap forward for Solaris as a desktop platform.

There exists, indeed, open source and free alternatives such as Xine and MPlayer. To be fair, I never had any problem with Xine: I'm a faithful Xine user since so many years. The only issues I had are related to Blastwave's Xine packages which seem to broke many Nevada builds ago (b110 more or less). To play encrypted DVDs you also need to compile your own libdvdcss, which may be an issue for a non technical user.

If you're willing to support companies like Fluendo, which is supporting the Solaris Operating System even for desktop products like a DVD Player, please don't think twice and buy it.


Sunday, November 1, 2009

Jump Into the Past: a Duke 3D revival



"Damn! Those alien bas***ds are gonna pay for shooting up my ride."

Does this opening sentence sound familiar to you? Two days ago, after installing Duke Nukem 3D on my iPhone, I launched the game and was welcome by it.

I used to play with Duke on a PC powered with a Pentium 133 a long, long time ago. When I saw it on the App Store, by chance, I couldn't resist buying it and playing it again.

The port is really good, although still incomplete. The primary three episodes are there (L.A. Meltdown, I didn't even remember the name!) and the feeling is just the same. I noticed some graphical detriment that I wouldn't call minor:
mirror effects, for example, were things that made Duke 3D so cool,
back in the 90's. Playability on the iPhone isn't so good, either, in
my opinion. The user is given two choices: digital and analog controls.


Digital controls, whose screenshot is shown in the next picture,
is the easiest control to get accustomed to. By sliding your finger
onto four buttons you can control Duke's movements just as if you were using a joystick. While playing you still need to use additional buttons (such as jump or use): these buttons are located on the uppermost right corner of
the screen and they're sufficiently small so as you confuse them one another.

The analog controls, at first impression, seem more intuitive because the user is given two separate joysticks:


Nonetheless, I found these controls pretty hard to manage and quickly switched to using the digital ones exclusively.

If you're feeling some kind of longing for such an old game, Duke Nukem 3D can be purchased right now on the App Store at just 0.79 Eur. Much less than an espresso, here in Spain.

Thursday, October 29, 2009

Sun xVM VirtualBox 3.0.10 has been released

Today, October 29th, Sun released a minor update for its flagship desktop virtualization solution, xVM VirtualBox. The changelog of VirtualBox 3.0.10 is the following:
  • VMM: guest SMP stability fixes
  • VMM: fixed guru meditation with nested paging and SMP guests (bug #5222)
  • VMM: changed VT-x/AMD-V usage to detect other active
    hypervisors; necessary for e.g. Windows 7 XP compatibility mode
    (Windows & Mac OS X hosts only; bug #4239)
  • VMM: guru meditation during SCO OpenServer installation and reboot (VT-x only; bug #5164)
  • VMM: fixed accessed bit handling in certain cases (bug #5248)
  • VMM: fixed VPID flushing (VT-x only)
  • VMM: fixed broken nested paging for 64 bits guests on 32 bits hosts (AMD-V only; bug #5285)
  • VMM: fixed loading of old saved states/snapshots (bug #3984)
  • Mac OS X hosts: fixed memory leaks (bug #5084)
  • Mac OS X hosts (Snow Leopard): fixed redraw problem in a dual screen setup (bug #4942)
  • Windows hosts: installer updates for Windows 7
  • Solaris hosts: out of memory handled incorrectly (bug #5241)
  • Solaris hosts: the previous fix for #5077 broke the DVD host support on Solaris 10 (VBox 3.0.8 regression)
  • Linux hosts: fixed module compilation against Linux 2.6.32rc4 and later
  • Guest Additions: fixed possible guest OS kernel memory exhaustion
  • Guest Additions: fixed stability issues with SMP guests
  • Windows Additions: fixed color depth issue with low resolution hosts, netbooks, etc. (bug #4935)
  • Windows Additions: fixed NO_MORE_FILES error when saving to shared folders (bug #4106)
  • Windows Additions: fixed subdirectory creation on shared folders (bug #4299)
  • Linux Additions: sendfile() returned -EOVERFLOW when executed on a shared folder (bug #2921)
  • Linux Additions: fixed incorrect disk usage value (non-Windows hosts only)
  • Linux installer: register the module sources at DKMS even if the package provides proper modules for the current running kernel
  • 3D support: removed invalid OpenGL assertion (bug #5158)
  • Network: fixed the Am79C973 PCNet emulation for QNX (and probably other) guests (bug #3206)
  • VMDK: fix handling of split image variants
  • VHD: do not delay updating the footer when expanding the image to prevent image inconsistency
  • USB: stability fix for some USB 2.0 devices
  • GUI: added a search index to the .chm help file
  • GUI/Windows hosts: fixed CapsLock handling on French keyboards (bug #2025)
  • Shared clipboard/X11 hosts: fixed a crash when clipboard initialisation failed (bug #4987)

If you want to give VirtualBox a try, you can go and download the package for your platform of choice.

Sunday, October 25, 2009

A Tribute to a Nine-Time World Champion!

Valentino Rossi, Il Dottore (The Doctor), is MotoGP 2009 World Champion. 9-times World Champion, 7th as MotoGP driver, more than 200 contented race, more than 100 won races, more than 150 podiums and more than 150 pole positions. Valentino Rossi is a MotoGP legend and, possibly, the best driver in motorcycling history.

Congratulations, Valentino.

Saturday, October 24, 2009

Apple Discontinues Mac OS/X ZFS Project

One of the reasons I really love Solaris 10 (and OpenSolaris) is ZFS. I'm also running Solaris at home because of ZFS. I'd also thought about buying an Apple machine some day or the other but was waiting about ZFS being integrated into Mac OS/X. Well, it seems that the game is over:


Apple has posted a note on its ZFS project web page informing the users that the project is being discontinued. Apparently, there's a ZFS MacOS refugee camp (in their own words) on Google Groups.

I'm really sorry about that. ZFS is a great technology and it would have fitted very well on Mac OS/X, although it's (mainly) a consumer oriented Operating System. I was wondering about a ZFS-enabled Time Machine (sort of OpenSolaris Time Slider). Real cool, but it'll never be: rumors suggest that it was a political, rather than technical choice.

Nonetheless I think Mac lovers have lost the opportunity of running ZFS as their file system. As far as it concerns myself, a real argument about switching (at least the laptop) has just faded away and I think I'll keep on sticking with Sun Desktops and with some compatible laptop here at home.




Friday, October 23, 2009

Cookies best practices: Cookies, WebSphere, LTPA, Single Sign-On

Yesterday I had to debug a strange problem that was affecting our security infrastructure. It seemed as though, despite being transmitting a Single Sign-On token as a cookie to web applications, they couldn't gain access to some protected resources any more. We're using an IBM DataPower SOA Appliance to implement the user registry and the LTPA (Lightweight Third Party Authentication) token generation and the IBM WebSphere Application Server is configured to accept a Single Sign-on LTPA token. Nothing in the WebSphere Application Server configuration had changed and very little diffs were applied to our DataPower appliance in the testing environment. Despite the changed code was easy to double check, we immediately thought about a cookie-related problem and troubleshooting was straightforward, luckily.

I think it's worth describing what was going on because I often felt common misconceptions, or simply not enough knowledge, about cookies.

What a cookie is

Cookies were invented by venerable Netscape Corporation as a very first mean of providing some sort of state to an otherwise stateless protocol, such as HTTP is. Nowadays we're used to interacting with stateful web applications. That illusion is brought to us by some sort of an user session implementation in web and application server where such applications are run: as far as it concerns the web server, each one of the HTTP requests originating from our web browser isn't distinguishable to previous ones we might have done. The correlation is done on the server side by means of the information our browser (usually a session ID) sends along with the HTTP requests. Cookies were invented to solve this problem, although nowadays some application server may rely on other techniques: a piece of information our browser attaches on the HTTP request (in the form of a header). Cookies structure and behavior is described in RFC-2965.

Cookie behavior is pretty simple: they're simple text structure, they have a name, they might have an expiration date, they might specify whether they're meant to be sent on an encrypted connection only, they have a domain and a path and an arbitrary bucket of name-value pairs.

When the browser sends a cookie

Cookies, obviously, aren't indiscriminately attached to every HTTP requests originating from your browser. If a cookie is valid (has not expired) the browser send a cookie back with an HTTP request if the request is directed to the cookie domain to a resource contained in the cookie path. If a cookie's domain is www.example.com, it won't be sent back with a request to another.example.com. because the domains differ. Nor will a cookie be sent to www.example.com/pages/resource.jsp if the cookie path is /protected.

Pros and cons

Cookie domain and path are a powerful mechanism to isolate your cookie and avoid useless server resources' consumption analyzing cookie that are not used by specific applications. Setting a path correctly can help you avoid cookie attribute clashes (same name, domain and path) and restrict cookie usage only in the application that generates them. In the Java EE world, for example, an application could set a cookie's path to the context path of the Java EE web module so that the cookie is never sent to any other application. You might also decide to use a sub-path inside your own application to lower the request size, avoid processing of unnecessary information and lower the chances that cookies might be used in circumstances they weren't designed for. On the other hand, to implement basic inter-application communication, you might decide to just use the / path so that a cookie may be shared by more than one application in the same domain.

In any case, although this article is not about cookies security practices, I'll warn you against using cookies to store sensitive information, unless you implement the necessary precautions (for example, by using them on encrypted connections only).

The solution

The solution of our problem was trivial: because of a glitch, an LTPA token was being transmitted on a cookie whose path wasn't /. Being a Single Sign-On token in a Java EE environment deployed upon instances of IBM WebSphere Application Server, it was essential that the LTPA cookie was received by the application server when accessing protected resources of every application in the same realm. Setting the path to any other subdirectory was defying the Single Sign-On token purpose. WebSphere was correctly redirecting us to our corporate login page just because the cookie wasn't included in the request when jumping from one application to another.

Wednesday, October 21, 2009

HP Solution Center doesn't work in Windows 7

That's the only bad news after a flawless upgrade of a virtualized instance of Windows Vista Ultimate SP2 to Windows 7 Ultimate. The solution center refuses to start claiming that the device is not correctly set up.


I just checked HP website to see if HP Solution Center was available for HP OfficeJet 6500 on Windows 7 and, unfortunately, just a laconic one megabyte USERHPNDU_2017.exe file is present.

Users on HP Website report that reinstalling the Vista software on Windows 7 running setup.exe in Vista compatibility mode should suffice. I'll report on it. Meanwhile I tried to run the already installed software setting the appropriate compatibility flags but it keeps on complaining about an incomplete configuration.

Luckily, that's just a testing Virtual Machine. I wouldn't like to pay-so-much for a Windows upgrade just to discover, once more, that some of my hardware is not compatible.

Wednesday, October 14, 2009

Boot Configuration Data: removing boot options in Windows Vista

If you tweaked boot options in Windows versions earlier than Vista, you're probably familiar with boot.ini and friends. Today I wanted to give Windows 7 a try and launched the upgrade from Windows Vista Ultimate to Windows 7 Ultimate. Despite the compatibility check performed by the installer did not complain about anything, the installation failed: system restarts always ended with a BSOD. Fortunately, the system upgrade process left Windows Vista untouched and I could boot into it and remove stale installation files.

The last thing I had to remove were the boot options corresponding to the Windows Setup program. Windows Vista introduced a new boot loader architecture and a set of commands to interact with the storage system which holds the boot loader configuration: bcdedit. bcdedit is the Windows Vista equivalent of Solaris' beadm. This is good news: no more tweaking ini files.

To view the current configuration you can issue the following command (beware that you must run the bcdedit command in a command prompt run as Administrator):

bcdedit /enum

[snip]
Windows Setup
-------------
identifier              {cbd971bf-b7b8-4885-951a-fa03044f5d71}
device                  partition=C:
path                    \$WINDOWS.~BT\Windows\system32\winload.exe
description             Windows Setup
locale                  en-US
inherit                 {bootloadersettings}
osdevice                partition=C:
systemroot              \$WINDOWS.~BT\Windows
nx                      OptOut
detecthal               Yes
winpe                   Yes
[snip]

To remove the Windows Setup boot menu entry I issued the following command:

bcdedit /delete {cbd971bf-b7b8-4885-951a-fa03044f5d71}

and the job was done.

Sunday, October 11, 2009

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, October 8, 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.

Wednesday, October 7, 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, October 4, 2009

(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.