Friday, August 7, 2009

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

11 comments:

Anonymous said...

thank you for this article!
it saved my night :)

Krupakar said...

I have an facebook kind of webapplication which is deployed in glassfish.
The user want's to upload his photos using my application. I want to store these images on the filesystem outside my web application deployment .
I know it is not possible to acces images from the filesystem in the web application.
I tried this below..bit it still didn't work.. .Could any one help what's wrong with this...?
1>
sun-web.xml present in deployment in glassfish server as FinanceFaceBook/Webcontent/WEB-INF/sun-web.xml
sun-web.xml content is xml version="1.0" encoding="UTF-8"?>sun-web-app> sun-web-app>2> my jsp page acessing the image as
img src="/faces/thumbs/dummy.jpg" width="68" height="68" />
3> My images are located at : /opt/PBMG/stage/SONYBMGBUZZ/facebook/thumbs/dummy.jpg
Please suggest any idea,

Anonymous said...

Can I upload Files in an alternatedocroot?? I tried that but the files dont upload to the directory. I work with a servlet for the upload, but files dont save in the external directory.

Harkiran said...

Yes, the files can be uploaded. Make sure you have read/write permission on the directory at Operating System level.

Anonymous said...

Thanks for your tips, I verified and I have read/write Permissions, but files don´t upload to the external directory. The servlet Only create the folders. My servlet works, I uploaded files in a folder into the glassfish domain. The OS is a Unix System. I don´t know what other to check. Thanks for your help. Blessings for You.

roberto.cisternino@ebpages.eu said...

Hello,
I would appreciate some feedback on successfully using the alternatedocroot_* option on either a Glassfish 3.1.1 virtual host or within the glassfish-web.xml descriptor.

I have tried both cases but I always obtain a 404.

Inside the glassfish-web.xml descriptor I made two tests:
1)
<property name="alternatedocroot_1" value="from=/store/* dir=C:/store"/>
2)
<property name="alternatedocroot_1" value="from=/* dir=C:/store"/>

I am using the catalina Web-DAV servlet provided along with Glassfish 3.1.1 and I found it is initially retrieving the alternate doc roots I provide, but then it doesn't work.

My web context is named "dav", so the url is like:

http://domain.com/dav/

In case (1) I try http://domain.com/dav/store
and I have back a 404.

In case (2) I try http://domain.com/dav
but I obtain the default root of the web application and not the alternative root.

I would appreciate some help, thank you in advance.

Roberto

Anonymous said...

i will create too much sitemap files and must be in root folder. And they will change frequenty. based on this document: http://stackoverflow.com/a/8889096/921535
i want to use virtual directories for overcome performance problems. how can i do this ? i don't want to keep sitemap files in root folder but it can be accessible from root folder :S.

@Atul*** said...

Nice Article. Thanks :)

Anonymous said...

Hi,

I have a configuration folder(named : config), in which all my resources (RB) and other many property files are there.. where can I load this config folder. I tried as per your suggestion, but its not working. I added following entry in glassfish-web.xml



As my java files would be reading and loading configurations directly from that physical location. But its not working..

Any suggestions ?

Anonymous said...

Thank you I'v been looking for such a solution:)

Unknown said...

Thanks, I very much understanding now

Post a Comment