Saturday, August 29, 2009

Map an external directory into your application directory in Tomcat

This article will explain how to map an external directory into your application directory (i.e. how to create a virtual directory) using Tomcat.
Let me first describe why you may need to create a virtual directory in your application. Suppose your application allows a user to upload images and there is no restriction on the total number of images that can be uploaded in your application. The folder in which the images are loaded will keep on growing in size from KBs to MBs to GBs, eventually the size of the application will also grow which will hamper the speed of your application.

Creating a virtual directory inside your context in Glassfish v3 Preview is straight forward as discussed in my previous post. While setting up the same in tomcat you need to make sure if you are using Tomcat 6 then it is version 6.0.18 or higher. The method that I had followed from the Tomcat manual does not works in version 6.0.16.

You might know that you can create a virtual host in tomcat and run your application by placing it anywhere outside of the "webapps" folder. Basically you are creating a new context which is outside the "webapps" folder. What I will be talking about is having something like "/yourContext/images", where the "images" folder is anywhere outside the "yourContext" folder which is inside "webapps" i.e. "images" can be anywhere other than "/webapps/yourContext/images".

Let us begin with what the Tomcat documentation says here,

The Context element represents a web application, which is run within a particular virtual host. Each web application is based on a Web Application Archive (WAR) file, or a corresponding directory containing the corresponding unpacked contents, as described in the Servlet Specification (version 2.2 or later).
You may define as many Context elements as you wish. Each such Context MUST have a unique context path. In addition, a Context must be present with a context path equal to a zero-length string. This Context becomes the default web application for this virtual host, and is used to process all requests that do not match any other Context's context path.

For Tomcat 6, unlike Tomcat 4.x, it is NOT recommended to place elements directly in the server.xml file. This is because it makes modifing the Context configuration more invasive since the main conf/server.xml file cannot be reloaded without restarting Tomcat.

Context elements may be explicitly defined:
  • In the $CATALINA_BASE/conf/context.xml file: the Context element information will be loaded by all webapps.
  • In the $CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default file: the Context element information will be loaded by all webapps of that host.
  • In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml extension) will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar. The default web application may be defined by using a file called ROOT.xml.
  • Only if a context file does not exist for the application in the $CATALINA_BASE/conf/[enginename]/[hostname]/, in an individual file at /META-INF/context.xml inside the application files. If the web application is packaged as a WAR then /META-INF/context.xml will be copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to match the application's context path. Once this file exists, it will not be replaced if a new WAR with a newer /META-INF/context.xml is placed in the host's appBase.
  • Inside a Host element in the main conf/server.xml.
With the exception of server.xml, files that define Context elements may only define a single Context element.

Let us concentrate on the bullet point:
  • In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml extension) will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar. The default web application may be defined by using a file called ROOT.xml.
It tells you how to create a multilevel context path, in other words how to create a virtual directory inside your context.

The method is simple, which involves the following steps:

1. Open the CATALINA_HOME location which is where you have installed tomcat.
2. Locate and change directory to "conf"
3. Now create a directory called "Catalina".
4. Now create another directory "localhost" inside the newly created directory "Catalina".
5. Inside "localhost" create a file called "yourContext#images.xml", replacing "yourContext" with your context name.
6. Now inside the above xml file put the following line:
<context docbase="d:/images"></context>
7. Now restart Tomcat server.

Now, when you load the Tomcat Manager you will find a new entry for the context "yourContext/images". Now this will point to the "images" directory in D drive as in the above example.

All the request made to "/yourContext/images" will be mapped to your directory "d:\images".

Now, you have an external directory mapped into your context which can be used to upload files or images.

Tuesday, August 11, 2009

Retrieving Automatically Generated Keys

Retrieving Automatically Generated Keys

Many DBMSs automatically generate a unique key field when a new row is inserted into a table. Methods and constants added in the JDBC 3.0 API make it possible to retrieve these keys, which is a two-step process. First the driver is alerted that it should make the keys available for retrieval. The second step is to access the generated keys by calling the Statement method getGeneratedKeys. The rest of this section explains these two steps more fully.
  1. Step One - Tell the driver that it should make automatically generated keys available for retrieval. This is done when an SQL statement is sent to the DBMS, which for Statement objects, is when the statement is executed. Three new versions of the method executeUpdate and three new versions of the method execute signal the driver about making automatically generated keys available. These six new methods take two parameters, the first being in all cases an SQL INSERT statement. The second parameter is either a constant indicating whether to make all generated keys retrievable (Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS) or an array indicating which specific key columns should be made retrievable. The array elements are either the indexes of the columns to be returned or the names of the columns to be returned.

    Note that although it is possible to use the method execute for executing a DML (Data Manipulation Language) statement, this method is generally reserved for executing CallableStatement objects that produce multiple return values.
    • For a PreparedStatement object, the SQL statement is sent to the DBMS to be precompiled when the PreparedStatement object is created with one of the Connection.prepareStatement methods. Thus, the driver is notified about making automatically generated keys retrievable via these methods.


  2. Step Two - After the driver has been notified about making automatically generated keys available for retrieval, the keys can be retrieved by calling the Statement method getGeneratedKeys. This method returns a ResultSet object, with each row being a generated key. If there are no automaticallty generated keys, the ResultSet object will be empty.
    The following code fragment creates a Statement object and signals the driver that it should be able to return any keys that are automatically generated as a result of executing the statement. The example then retrieves the keys that were generated and prints them out. If there are no generated keys, the printout says that there are none.
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
"'PARKER', 'DOROTHY', 'USA', keyColumn";

int rows = stmt.executeUpdate(sql,
Statement.RETURN_GENERATED_KEYS);

ResultSet rs = stmt.getGeneratedKeys();


int rows = stmt.executeUpdate(sql,
Statement.RETURN_GENERATED_KEYS);

ResultSet rs = stmt.getGeneratedKeys();
if (rs.next())
{
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
do {
for (int i = 1; i <= colCount; i++)   
{   
String key = rs.getString(i);     
System.out.println("key " + i + "is " + key); 
} 
} 
while (rs.next();)   }
else  
{ System.out.println("There are no generated keys."); }
Instead of telling the driver to make all automatically-generated keys available, it is possible to tell the driver to make particular columns retrievable. The following code fragment uses an array of column indexes (in this case, an array with one element) to indicate which columns with an automatically-generated key should be made available for retrieval.
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
"'PARKER', 'DOROTHY', 'USA', keyColumn";
int [] indexes = {4};
int rows = stmt.executeUpdate(sql, indexes);
The following code fragment shows a third alternative-supplying an array of column names to indicate which ResultSet columns to make available. In this case, the driver is told to make the automatically-generated key in the column AUTHOR_ID retrievable.
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
"'PARKER', 'DOROTHY', 'USA', keyColumn";
String [] keyColumn = {"AUTHOR_ID"};
int rows = stmt.executeUpdate(sql, keyColumn);
The above has been taken from http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/statement.html#1000569

Sunday, August 9, 2009

How to setup Java under Linux

For Fedora please visit the below link and check the post by "dinob" (#6)

http://forums.fedoraforum.org/showthread.php?t=85446

For Ubuntu please visit the link below and check the post by "hod139" (#1)

http://ubuntuforums.org/showthread.php?t=201378

Friday, August 7, 2009

Compiling and installing a Linux Kernel

Compiling custom kernel has its own advantages and disadvantages. However, new Linux user / admin find it difficult to compile Linux kernel. Compiling kernel needs to understand few things and then just type couple of commands. This step by step howto covers compiling Linux kernel.

Step # 1 Get Latest Linux kernel code


Visit http://kernel.org/ and download the latest source code. File name would be linux-x.y.z.tar.bz2, where x.y.z is actual version number. For example file inux-2.6.25.tar.bz2 represents 2.6.25 kernel version.

Step # 2 Extract tar (.tar.bz3) file

Type the following command:

# tar -xjvf linux-2.6.25.tar.bz2 -C /usr/src
# cd /usr/src

Step # 3 Configure kernel

Before you configure kernel make sure you have development tools (gcc compilers and related tools) are installed on your system.
Now you can start kernel configuration by typing any one of the command:
  • $ make menuconfig - Text based color menus, radiolists & dialogs. This option also useful on remote server if you wanna compile kernel remotely.
  • $ make xconfig - X windows (Qt) based configuration tool, works best under KDE desktop
  • $ make gconfig - X windows (Gtk) based configuration tool, works best under Gnome Dekstop.
For example make menuconfig command launches following screen:

$ make menuconfig

You have to select different options as per your need. Each configuration option has HELP button associated with it so select help button to get help.

Step # 4 Compile kernel

Start compiling to create a compressed kernel image, enter:

$ make


Start compiling to kernel modules:

$ make modules

Install kernel modules (become a root user, use su command):

$ su -
# make modules_install

Step # 5 Install kernel

So far we have compiled kernel and installed kernel modules. It is time to install kernel itself.

# make install

It will install three files into /boot directory as well as modification to your kernel grub configuration file:
  • System.map-2.6.25
  • config-2.6.25
  • vmlinuz-2.6.25

Step # 6: Create an initrd image

Type the following command at a shell prompt:

# cd /boot
# mkinitrd -o initrd.img-2.6.25 2.6.25


initrd images contains device driver which needed to load rest of the operating system later on. Not all computer requires initrd, but it is safe to create one.

Step # 7 Modify Grub configuration file - /boot/grub/menu.lst

Open file using vi:

# vi /boot/grub/menu.lst
title           Debian GNU/Linux, kernel 2.6.25 Default
root            (hd0,0)
kernel          /boot/vmlinuz root=/dev/hdb1 ro
initrd          /boot/initrd.img-2.6.25
savedefault
boot

Remember to setup correct root=/dev/hdXX device. Save and close the file. If you think editing and writing all lines by hand is too much for you, try out update-grub command to update the lines for each kernel in /boot/grub/menu.lst file. Just type the command:
# update-grub

Step # 8 : Reboot computer and boot into your new kernel

Just issue reboot command:

# reboot

For more information see:
  • Our Exploring Linux kernel article and Compiling Linux Kernel module only.
  • Official README file has more information on kernel and software requirement to compile it. This file is kernel source directory tree.
  • Documentation/ directory has interesting kernel documentation for you in kernel source tree.

Map an external directory into Glassfish

In this article I'll try to explain how to map an external directory into the Glassfish application server. Until you have experienced the need for mapping an external directory into Glassfish, the first thing that will come to your mind what is the need to do so.

The reason to map an external directory into the server may be different for different kind of applications. One of the situations may be when an application has to upload lots of files on the server which may be images, text documents, PDFs, Word Documents or other format of files. The files uploaded on a daily basis will eat up disk space and make the context of the application grow in size may be on a daily basis or even hourly basis. A best example of such an application may be an application which allows users to upload images. An inventory management system may also allow the user to upload images of the inventory items. And in cases where all the inventory items has at least one image attached to it the size of the folder storing the images may easily go beyond 2GB. Imagine a growing inventory of more than 24,000 items with an option to add two images for an item. If the server is running on Windows with FAT32 file system then there will be another problem when the folder size grows to 2GB. FAT32 does not supports folder size of more than 2GB. So, while uploading files on the server you should be careful and have to manage the files by segregating them into different folders, which may be by date and time.

Now getting back to the main topic of creating virtual directories. This can be easily done using the Glassfish application server. GlassFish v2 Build 40 adds support for alternate docroots to web applications. Previously, support for alternate docroots was limited to virtual servers.

Alternate docroots allow web applications to serve requests for certain resources from outside their own docroot, based on whether those requests match one (or more) of the URI patterns of the web application's alternate docroots.

This means that web applications no longer need to bundle all their resources. Instead, part of their resources may be outsourced into server directories outside the web application's docroot, so-called alternate docroots, where they may be shared with other web applications.
If a request matches an alternate docroot's URI pattern, it will be mapped to the alternate docroot by appending the request URI (minus the web application's context root!) to the alternate docroot's physical location (directory).

The URI patterns of alternate docroots of web applications support exact, path prefix, and extension matches, just like their counterparts for virtual servers. If a request matches multiple URI patterns, the alternate docroot is determined according to the following precedence order:
  • Exact match
  • Longest path match
  • Extension match
Alternate docroots of web applications are configured as sun-web.xml properties, using the same syntax as alternate docroots for virtual servers.

Example: The following sun-web.xml specifies 3 alternate docroots:

<sun-web-app>
     <property name="alternatedocroot_1" value="from=/my.jpg dir=/srv/images/jpg"/>
     <property name="alternatedocroot_2" value="from=*.jpg dir=/srv/images/jpg"/>
     <property name="alternatedocroot_3" value="from=/jpg/* dir=/src/images"/>
</sun-web-app>


The value of each alternate docroot has two name-value components: The first component (with name from) specifies the alternate docroot's URI pattern as its value, and the second component (with name dir) specifies the alternate docroot's physical location (directory) as its value.

In this example, the URI pattern of the first alternate docroot uses an exact match, whereas the URI patterns of the 2nd and 3rd alternate docroots use extension and path prefix matches, respectively.

Assume the above sun-web.xml belongs to a web application deployed at http://{hostName}:{portNumber}/myapp.

The first alternate docroot will cause any requests with this URL:

http://{hostName}:{portNumber}/myapp/my.jpg
to be mapped to this resource:

/svr/images/jpg/my.jpg

while the 2nd alternate docroot will cause any requests with a *.jpg suffix, as in:

http://{hostName}:{portNumber}/myapp/*.jpg

to be served from this physical location:

/svr/images/jpg

whereas the 3rd alternate docroot will cause any requests whose URI starts with /myapp/jpg/, as in:

http://{hostName}:{portNumber}/myapp/jpg/*

to be served from the same directory as the 2nd alternate docroot.

For example, the 2nd alternate docroot maps this request:

http://{hostName}:{portNumber}/myapp/abc/def/my.jpg

to:

/srv/images/jpg/abc/def/my.jpg

and the 3rd alternate docroot maps:

http://{hostName}:{portNumber}/myapp/jpg/abc/resource

to:

/srv/images/jpg/abc/resource

If a request does not match any of the target web application's alternate docroots, or if the target web application does not specify any alternate docroots, the request will be served from the web application's standard docroot, as usual.

One point to note is that the physical path and the one in the 'sun-web.xml' should match. For example in
<property name="alternatedocroot_3" value="from=/jpg/* dir=/src/images"/>

The above will map to /src/images/jpg. So, you need to make sure that whatever is after "from=" matches to a path inside the "images" folder. In the above examples the path is from Unix/Linux systems. To use on a Windows machine use something like "d:/src/images".

Wednesday, August 5, 2009

Install KDE on Ubuntu

KDE is a powerful graphical desktop environment for Unix workstations. It combines ease of use, contemporary functionality and outstanding graphical design with the technological superiority of the Unix operating system. KDE is a completely new desktop, incorporating a large suite of applications for Unix workstations. While KDE includes a window manager, file manager, panel, control center and many other components that one would expect to be part of a contemporary desktop environment, the true strength of this exceptional environment lies in the interoperability of its components.
If you have used Fedora in the past then you must be aware of the fact that it gives you an option to install both Gnome and KDE. This option had been available since the earlier days when Fedora used to be RedHat Linux.
If anyone of you misses KDE while working on Ubuntu you can install KDE on Ubuntu using the simple steps described below.
By default Ubuntu desktop installation will install gnome desktop enviroment and if you want to install KDE desktop enviroment you have three options. Those options are
kubuntu-desktop -This is the recommended metapackage to install; the full Kubuntu installation, with all the Kubuntu recommended packages. This includes OpenOffice, Kontact, Konversation, amaroK, K3B, and others.
kde -This will install the following KDE packages: kde-amusements, kdeaccessibility, kdeaddons, kdeadmin, kdeartwork, kdegraphics, kdemultimedia, kdenetwork, kdepim, kdesdk, kdeutils, kdewebdev, kdevelop3 and the kde-core metapackage
kde-core -This will install the core — the bare-minimum required– of KDE. That is, kdebase, kdelibs, arts and fontconfig.
If you choose to not install kubuntu-desktop, then you can still get all the Kubuntu-specific tweaks by installing the kubuntu-default-settings package.
First thing you need to make sure you have universe source list under
/etc/apt/sources.list file
If you want to install kubuntu-desktop use the following command
sudo apt-get install kubuntu-desktop
This will starts installing all the required packages you can see in the following screen.
During this installation process, you will be asked whether you want to use KDM or GDM as your default display manager. If you think you’ll use KDE , make KDM your default. If you think you’ll use Gnome , keep GDM as your default.Select which one is best for you.
This will complete the installation now you need to logout from ubuntu gnome session and now you are on ubuntu login screen in this you need to select options—> selectsession.
Uninstall KDE in ubuntu
If for any reasons you want to uninstall KDE session use the following command
sudo apt-get remove kubuntu-desktop

Fixing sound problems in Ubuntu 9.04 (Module snd_hda_intel is in use)

I had installed Ubuntu 9.04 on my dell laptop and strangely there was a problem: there was no sound!!
Although, there was sound on Ubuntu 8.04 so I did not expected this to happen in the version 9.04. The sound problem was also there in Fedora 11. The error I got was Module 'snd_hda_intel' is in use. After trying Ubuntu 8.04 live CD I got sound, so I decided to install Ubuntu 8.04 and wait for a fix on Fedora 11. After installation I found out Ubuntu 8.04 did not detected that my laptop has wifi and there was no option to connect to my wireless network. Now, I had sound but no wireless internet on my laptop even when it was wifi enabled :-(
I then decided to upgrade it to Ubuntu 9.04 and see if I can get the sound to work. After installing Ubuntu 9.04 wifi started working but no sound as it was in Fedora 11. So, it appears there is something in the kernel which does not lets the sound to play.
After googling for a couple of days I found something to fix the sound problem on Ubuntu 9.04. I am not sure if this will work for Fedora 11 or not.
Below are the solutions I found on http://www.ubuntuforums.org/
1. By gkgarg24, http://ubuntuforums.org/showthread.php?t=1136670&page=2
Hey Guys,
I was also having same problem after upgrade to ubuntu 9.04. I am running it on Dell Inspiron 1420n. I did the following steps after searching through forums.
1>Run the following commmand
sudo gedit /etc/modprobe.d/alsa-base
2>Add the following text to it.
options snd-intel8x0 ac97_quirk=1 buggy_irq=1 enable=1 index=0
options snd-hda-intel model=3stack enable=yes
options snd-hda-intel model=auto position_fix=1 enable=yes
3>Save the file.
4>Rune the following commend :
sudo /etc/init.d/alsa-utils restart
5>If this does not work try rebooting machine. Sound should be back again.
Hope this helps!
2. By babusar, http://ubuntuforums.org/showthread.php?t=1136670&page=4
I had this same problem when upgrading from 8.04 to 8.10 on my laptop and the same thing has happened again when upgrading to 9.04. I've found a work around that has worked for both these upgrades. This is taken from Bug #286610:
you can fix it easily yourself by adding
options snd-hda-intel model=laptop enable=1 index=0
to the file /etc/modprobe.d/options. If you don't know how: Press Alt+F2, type for example
gksu gedit /etc/modprobe.d/options
press enter, write the options line above in it, save, reboot and everything should be fine.
It's worked fine for me on my HP 6735s laptop. Hope it helps.
Michael
3. By 4thfloorstudios, http://ubuntuforums.org/showthread.php?t=1136670&page=2
Ok, found out what is working to at least hear anything
- Boot with kernel 2.6.27-11
- Set all audio devices to "OSS"
I had tried all three and the one which worked for me was the last one, booting into kernel 2.6.27. Magically there was sound when I booted into kernel 2.6.27 instead of kernel 2.6.28. If you do not have the option to boot into kernel 2.6.27 then you can download it from
http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.27/
Make sure the volume is not muted and is high enough to hear something.
Please note Ubuntu and Fedora both does not has MP3 support built into it. You will need to download free software to play MP3's on both Fedora and Ubuntu.