Rajendra's Blog
Passed SCEA5 Part1
Thank God. I have passed the Sun Certified Enterprise Architect (SCEA5) Part1 Exam with 57% score. This is the most difficult Sun Certification exam. This is because questions models real time scenarios which demands industry exposure. Two hours time was not sufficient to answer all the questions. I have left last six questions unanswered due to time constrain. Few questions are easy direct questions but most of the questions describes problem and asks you to architect solution for the problem. I took almost two and half week to prepare for the exam burning all my Christmas holidays,week-ends and comp-off vacation that we got for working weed ends in the company. I have put in tremendous hard work reading the following books with in two weeks. The books that I have referred are: 1) Elements of Reusable Object Oriented Software (GOF book) 2) Head First Design pattrens 3) Core J2EE patterns (Deepak Alur,John Crupi, Dan Malks) 4) Core Security patterns (Chris steel,R Nagappa, Ray Lai) 5) Core Servlets and Java Server Pages (Vol I by Marty Hall, Larry Brown) 6) Core Servlets and Java Server Pages (Vol II Marty Hall, Larry Brown, Yakoov) 7) Core Java Server Faces (David Geary, Cay HorstMaan) 8) SOA using Java web Services (Mark D Hansen) 9) Enterpise Java Beans( Bill Burke) 10) SCEA Study Guide (Mark Cade, Simon Robert). 11) http://java.boot.by/scea5-guide/ (Mikalai Zaikin) 12) Whiz Labs SCEA5 Mock EXam. I am happy that I have passed the exam otherwise I thought I should not go for second attempt as I am not spending any time with my family.
Posted at 03:08PM Mar 02, 2009 by Rajendra Gutupalli in Personal | Comments[2]
JavaFX Code Contest
Hey Do you know the JavaFX Contest from Sun. Yes I think you might be aware of this and you are on the way to register for the Contest.Let me pass the news for the techies and Students in India. Sun has announced Code JavaFX contest. Registration for the Contest is open from 16/02. JavaFX is descriptive scripting language for developing Rich internet Applications. It doesn't take much time to get familiarized with JavaFX if you are a Java developer.Don't Delay. Make use of this opportunity to learn JavaFx and propose Ideas and submit your project. Get appreciation from SUN. Visit Contest Page Today.
Posted at 10:42AM Feb 17, 2009 by Rajendra Gutupalli in Sun | Comments[0]
Listing Named Attributes
JSR-203 has a new feature that allows you to access named attributes associated with files. In my previous entry I described how to read and write named attributes in different operating systems. Here is the sample code using JSR-203 APIs lists the named attributes in a directory.
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.*;
public class NamedAttrs {
public static void main(String... args) throws Exception {
final Path path = Paths.get(args[0]);
Files.withDirectory(path, new DirectoryAction() {
public void invoke(DirectoryEntry entry) {
try {
NamedAttributeView nav = entry.getFileAttributeView(NamedAttributeView.class, true);
if (nav == null) {
throw new RuntimeException("Named Attributes are Not Supported");
}
Iterable list = nav.list();
if (list.iterator().hasNext()) {
System.out.println(entry.getName());
for (String item : list) {
System.out.println(" " + item);
}
}
} catch (IOException e) {
System.err.println("problem in reading named Attrs " + e.getMessage());
}
}
});
}
}
This code lists the files associated with named attributes similar to the tools 1. Streams 2. LADS which lists files associated with alternate data streams in Windows NTFS volumes. Windows XP does not have any commands to list the files which have alternate data streams. You can use the above tools to enumerate files which has named attributes. This tools works similar to above code. The greatness of the above code as you know is, it lists named attributes of files in all operating systems but this tools works in only Windows Operating System.
Posted at 03:54PM Jul 29, 2008 by Rajendra Gutupalli in Sun | Comments[0]
Purpose of Existence
I have been influenced by a friend of mine to join Sun Toast Masters Club in India. As it is aligned to my development plan, I joined the club recently and delivered my first speech. In my first speech I have to talk about my self, so I recollected some experiences from my childhood and talked about it in last Toast masters meeting. Transcript of my talk goes like this...
It is said four things are not returned if we do not utilize them properly. They are, The time spent, The opportunity lost, The arrow sped and The spoken word. I am reminded by this truth because three years back I attended toast masters program as a guest but somehow I neglected this opportunity. As they say better late than never finally I realized need for the same and now I am here in front of you giving my first ice-breaker speech.
Ok let me break the ice
with a
question.
What is the purpose of existence?
When I was a child I used
to think by
observing people. Okay we born. We grew up. We get educated, We do job.
We get
married and have children and then finally become old and die.
This
is the series of events that we see in most of the human lives. I did
not know the purpose of life until my beloved father breathed his
last breath.
Dear Tostmasters, My Name is Rajendra Vittal G. I born as a last kid to my parents. I have two brothers. I loved my father anything more than in this world. I just want to narrate two incidents connecting to my father.
I remember one incident which has strong influence in my life. My father was a smoker. He used to smoke six to eight cigarettes in a day. Every day I used to bring cigarettes from the near by shop. One day I remember in 7th class, my curious mind asked me, 'What would happen if I smoke? Does it taste like Lacto King chocolate which melts in my mouth?'. I wanted to feel the experience that my father enjoys. So One day my father asked to bring two cigarettes but I brought three cigarettes one for me. Looking around I kept one cigarette in my pocket. I went on to the terrace of my house sneaking like a snake. I lit a cigarette. You know what happened, I had a irritating intolerable cough. I thought my self how can my father smokes this stupid thing. Okay I should not judge result just by trying one time.Let me try for the second time. Second puff was same and third it tasted to my tongue and I felt thrilling sensation running through my blood. From then on I was smoking on and off not very regularly until I got married. After I got married my wife gave me a ultimatum. She said, either you give up smoking or give up me. I gave up smoking cigarettes. I am not narrating this incident as a great experience. This is a lesson for all fathers and mother too nowadays.
Let me tell you one more incident which changed my way of life. My father was hospitalized with mild heart-attack and left this world after one month struggling on the bed. I could not digest the separation of my father from me. I challenged God that you can take him from me but I will find him wherever he is. May be I got this confidence of challenging God, because during those days I read one wonderful book and I recommend you to read the book 'An Autobiography a Yogi by parmahamsa yoganada'.I wanted to renounce everything and go on the tour for search of Guru under whose guidance I can find my father. But I put off the plans as my mother was crying all these days and I don't want to cause any more pain to my mother. So what can I do for the search of a Guru without going here and there. I got a beautiful idea. Lets pray continuously until I find a Spiritual Guru. I continuously prayed for a Guru to unknown source silently in my mind through out day and night. Miraculously after a week I came to know about Guru “ Parthasarthi Rajagopalachari” president of Shri Ram Chandra Mission. I borrowed a book 'Reality At Dawn'. From his teaching I came to know that It is not my father I have to search for It is the ultimate father who created this whole universe. And I understood “There is no need to go any where to search for the Ultimate father 'God'. He is there right in your heart ”. Only thing is you have to experience it by being obedient to Guru.
After I read these
statements my heart
was filled with peace and the next day I joined the Shri Ram Chandra Mission
Let me conclude my Icebreaker speech
with a Wisdom that is passed on to me by My Master.
'Live as if you are going to die in
the next moment'
Posted at 12:37PM Jul 11, 2008 by Rajendra Gutupalli in Personal | Comments[2]
Named Attributes
Recently a new Java language API 'java.nio.flile.attribute.NamedAttributeView' has been added to JSR-203 specification. This allows to manipulate the extended attributes associated with a file in the file system. Operating Systems like Solaris, Linux and Windows support extended attributes in different ways. I will give an overview of what is an extended attribute and how can we add or delete the attributes in different file systems. Having known this file system feature makes you easier to play with the new Java technology APIs.
Every file system defines a set of file system specific attributes that describe the state of the file. These attributes are stored as part of metadata of the file. The attributes like filename, last modified time, size etc. are set by the file system when you create or modify a file. Extended attribute is a new file system feature that enables user to add an attribute to a file which is maintained in the metadata of the file.
To give a usage of named attribute, assume you have a collection of mp3 files which are hundred in number stored in a directory 'my_favorite_collection'. If you want to list out all the songs of a particular singer or songs of specific type( emotional, love, inspirational ) then there is no way if you depend on file system specific attributes. Extended attributes helps you to associate an attribute with the file. So you can add attributes like 'singer','type' etc. to the files and you can list out files of your choice by specifying a criteria.The way you associate an attribute to a file is different in different file systems. Lets first look at how we can add named attributes in Windows.
Windows NTFS file system supports alternate data streams. You can associate an alternate data streams to file as follows.
To display the contents of the named attributes use the following toolC:\> echo this content will be stored in the file sub stream > demo.txt:attr.1
In Windows Vista you can use DIR /R to display the alternate data streams of the files. You can add named attributes to symbolic links in Vista.C:\> more < demo.txt:attr.1
You can add a data stream to a file using 'type' command.
which copies the contents of demofile.txt as an alternate data stream to file demo.txt as an attribute name 'attr3'.C:\> type demofile.txt > demo.txt:attr3
The above type command does not recognize data streams instead you have to use 'more' command. There is no tool as such in windows to manipulate the alternate data streams. Now using JSR-203 API you can list all the attributes, add and delete attributes irrespective of the way they defined in file system.C:\> type demo.txt:attr3
Lets see how we can add extended attributes in Solaris:
In Solaris you can associate regular files as an extended attribute to a file or directory. To add a sub file to a file/directory you can use 'runat' tool which executes a command in extended attribute name space.
Remember that you can add named attributes only for a file or a directory but not for a symbolic link.To add a sub file /home/rajendra/filenotes to a file file.1, execute the following command.
To remove an extended attribute:user% runat file.1 cp /home/rajendra/filenotes attr.1
To open shell in the extended attribute name space for the file 'file.1', you can use the following commanduser% runat file.1 rm attr.1
Extended attributes in Linux:user% runat file.1 /bin/sh $
Linux supports extended attributes as name -value pairs. You can tag a file with a name value pairs. In order to add an extend attributes to files you have to enable this feature in the file system (ext2,ext3 or Reiser file systems)
you can enable this feature by remounting the partition as follows'setfattr' and 'getfattr' tools comes in handy to manipulate extended attributes in Linux. If you don't find this tools (in any Linux flavour) then you have to install the attr package in Ubuntu as follows.#sudo mount -o remount,user_xattr /
That's it. Now we can add the attributes. Final thing to remember is we have to add extended attributes in the 'user' name space. To add exteded attribute user.songs.title to the file songs1.mp3# apt-get install attr
To retrieve the attributes for the file song1.mp3$ setfattr -n user.songs.title -v “ My heart will go on” song1.mp3
To delete an attribute:$ getfattr -n user.songs.title song1.mp3 # file: song1.mp3 user.songs.title = song1.mp3.
That's it for now. Next we will see how easy to access extended attributes using JSR-203 APIs.$ setfattr -x user.songs.title song1.mp3
Posted at 09:22PM Jun 13, 2008 by Rajendra Gutupalli in Sun | Comments[2]
@SUNCertified(name="SCBCD5", scored="91%")
Do you wonder why I have named this bolg entry as Java technology annotation (JSR 175).
Really this is a cool feature that has been added in JavaSE5 changed the way of coding style for Enterprise Java Beans (EJB3).
In my previous company we used EJB2.1 for developing an enterprise distributed application. I just wanted to updated my EJB coding
skills, so I planned for writing SCBCD5 Sun Certification Exam. I have chosen following books and online material for preparation.
> EJB3 O'Reilly book.
This is a nice book which has two parts. First part explains about EJB3 and second part is JBoss workbook. I read only fist part and
used Netbeans 6 with glassfish V2 to practice EJB3 sample codes. I have noticed a typo in this book at page number 172 in chapter 9. It
says Query#getSingleResult() throws javax.persistence.EntityNotFoundException If no result returned. But this is not true,
Query.getSingleResult() throws javax.persistence.NoResultException if there is no result.
For the exam it is important to remember that the exceptions NoResultException and NonUniqueResultException thrown by this method
does not cause the transaction to roll back.
>SCBCD 5.0 Study Guide prepared by Mikalai Zaikin
- I want to thank Mikalai Zaikin for providing the preparation material. I have a short time to prepare so I have chosen this guide over
EJB3 specifications. He prepared this notes from the EJB3 Specifications.
>Sun Learning services EJB3 online training.
- This training is free for sun employees. It is exceptionally good.
>Enthuware mock exams
- These mock exams are very good really helps you for the exam.
>Whizlabs mock exams -
I tried only few exams because there are many typos and mistakes. I suggest them to get everything rectified.
>www.javapassion.com - This website also helps you a lot.
I studied long hours during the week ends and read the EJB3 O'Reilly book in last Diwali holidays. Last Monday I appeared for the exam
and scored 91%. My beak-up of marks are like following:
EJB 3.0 Overview - 100%
General EJB 3.0 Enterprise Bean knowledge - 83%
EJB 3.0 Session Bean Component Contract and Lifecyle - 100%
EJB 3.0 Message-Driven Bean Component Contract - 100%
Java Persistence API entities - 100%
Java Persistence Entity Operations -80%
Persistce Units and Persistence Contexts -100%
Java Persistence Query Lanage - 100%
Transactions - 80%
Exceptions - 100%
Security Management - 50%
Hope this helps!
Posted at 11:08AM Jun 04, 2008 by Rajendra Gutupalli in Sun | Comments[3]
Building OpenJDK with New NIO.2 patch
Source code for NIO.2 is available as a patch. I have applied the NIO.2 patch to the clone of OpenJDK repository and built the OpenJDK source in Solaris-Sparc and Ubuntu 8.04 on x86 machine.
Here are the steps I have followed.
> Install Mercurial 0.9.5 and update hg configuration file ~/.hgrc with forest extension.
> To install forest extension to mercurial
> export http_poxy=your proxy
> hg clone http://hg.akoha.org/hgforest
set the forest configuration variable to the path of forest.py in extensions section of ~/.hgrc file to enable forest extension
[extensions]
forest=/home/rajendra/hgforest/forest.py
>clone the jdk7 mercurial repository
hg fclone http://hg.openjdk.java.net/jdk7/tl jdk7
> download nio2-b90 patch
> move to folder jdk7/jdk and apply the nio patch with following command
patch -p1 < nio2-b90.patch
> follow the instructions for building OpenJDK
Here I executed the sample code DiskUsage.java which exhibits as df utility with the new build as follows.
$ ~/jdk7/build/bin/java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-b27) OpenJDK Client VM (build 12.0-b01, mixed mode) $~/jdk7/mytl/build/bin/java DiskUsage Filesystem kbytes used avail / (/dev/sda1) 113313700 5238532 102364464 /proc (proc) 0 0 0 (output discarded)
Try yourself and send feed-back, comments and suggestions to NIO OpenJDK project. I hope you will enjoy.
Posted at 03:34PM May 07, 2008 by Rajendra Gutupalli in Sun | Comments[7]
Building OpenJDK in Ubuntu 8.04
I tried building OpenJDK in Ubuntu 8.04 on x86 machine. I have come across with some issues which have work-around. After installing all the necessary applications for building JDK and setting environment, building failed with the following error.
<error>
/home/rajendra/jdk7/jdk7/hotspot/src/os/linux/vm/jvm_linux.cpp:179:
warning: deprecated conversion from string constant to ‘char*’
make[5]: *** [jvm_linux.o] Error 1
make[5]: Leaving directory
`/home/rajendra/jdk7/jdk7/build/hotspot/outputdir/linux_i486_compiler2/product'
make[4]: *** [the_vm] Error 2
</error>
It seems new compilers enables -Write-strings by default, work-around for this issue is to hack the make file hotspot/build/linux/makefiles/gcc.make and add the flag 'CFLAGS += -Wno-write-strings'. This solves the gcc failure.
After adding the flag build continued for some time and crashed with the following error.
Alan bateman has given work-around for this issue which worked for me. Alan suggested me to switch to bash or delete the /bin/sh and create a link "ln -s bash sh". I am happy this work-around solved my issue. After few minutes building again failed with the following error.<error> /home/rajendra/jdk7/jdk7/build /gensrc/java/nio/charset/CharsetEncoder.java:142: cannot find symbol symbol : class $replType$ location: class java.nio.charset.CharsetEncoder private $replType$ replacement; </error>
<error> /usr/bin/ld: cannot find -lXtst collect2: ld returned 1 exit status make[3]: *** [/home/rajendra/jdk7/jdk7/build/lib/i386/xawt/libmawt.so] Error 1 make[3]: Leaving directory `/home/rajendra/jdk7/jdk7/jdk/make/sun/xawt' make[2]: *** [all] Error </error>
For which I don't know the solution. If you have work-around or solution for the above issue please let me know.
Posted at 02:41PM May 06, 2008 by Rajendra Gutupalli in Sun | Comments[3]
New NIO OpenJDK Project
Today Mark Reinhold announced the creation of NIO Project to OpenJDK world. Alan Bateman is the project moderator. Click here to follow the NIO Project. The source code implementing the JSR-203 Specification is available as a patch in the project. To build the source code you need to clone the latest OpenJDK7 repository and follow the instructions given in the project page. This project hosts the development of next phase of the New I/O API's. To know more about the project subscribe to the mailing lists.
Enjoy trying the latest JavaAPI's.
Posted at 10:11PM Apr 29, 2008 by Rajendra Gutupalli in Sun | Comments[2]
JSR-203 New File System APIs
JSR-203 Specification gives clear description of the new API's. It does not take much time to get acquainted with the new API's. I just want to give some simple fundamentals for you to get started with the new API's. You can have a look at this entry and play around with new feature without much effort.
The method which enables Java virtual machine to access the underlying file system objects is Path.get() mehthod.
Path.get(“file”);
Path.get(String path) is a static method in java.nio.file package which returns a path object for the file given in a string. This path locates the file in the native (underlying) file system. Okay, after having got access to file what operations can we perform on this file: I will just list some of the interesting operations with code fragment examples.
>> Creating a symbolic link
Assume you have target folder “My Album” which is in home directory “/home/rajendra/”. Now if you want to create a symbolic link for this folder in shared NFS directory “/net/export/share/My Album” then you have to use Path#createSymbolicLink(Path target) method. The following code snippet creates a symbolic link.
Path target = Path.get("/home/rajendra/My Album");
Path symLink = Path.get("/net/export/share/My Album");
symLink.createSymbolicLink(target);
The first line creates the path object for the folder "/home/rajendra/My Album". Second line is the symbolic link which you want to create for the target file. Finally third line creates the symbolic link.
If you are creating a link in Vista Operating System use this method to create a link. This method creates a right link depending on the target.
>> Reading a symbolic link and traversing a directory
Path.readSysmbolicLink() method returns a path object for the target file to which the link is pointed.
Lets create a symbolic link to a directory in Vista and try to read the target of the link.
C:\>mklink SymLnkToMyDocs C:\MyDocs symbolic link created for SymLnkToMyDocs <<===>> C:\MyDocs
The following code fragment prints the target of symbolic link and tries to iterate the entries of target folder.
Path path = Path.get("c:\\SymLnkToMyDocs");
Path target = path.readSymbolicLink();
System.out.println("target file: "+ target);
DirectoryStream ds = path.newDirectoryStream((Filter)null);
for (DirectoryEntry de : ds){
System.out.println("file " + de.getFileName());
}
Here S.O.P. prints the target file: C:\MyDocs. But path.newDirectoryStream() with null value as filter throws “java.nio.file.NotDirectoryException: c:\SymLnkToMyDoc”
This is due to we have created wrong symbolic for the directory. In Vista if we do not mention /D option it treats the target as a file. If we had created a symbolic link with the following option then executing above program would not throw any exception.
That's it for today. We will explore other methods in the Path class in next entry.C:\> mklink /D SymLnkToMyDocs C:\MyDocs
Posted at 05:59PM Apr 02, 2008 by Rajendra Gutupalli in Sun | Comments[0]
Zip File System Provider Implementation details
As mentioned in my previous blog entry I will go into the implementation details of Zip file system provider. This will give you clear insight of developing a file system using new Java file system APIs ( NIO.2 ). A Zip provider allows the contents of a ZIP or JAR file to be viewed as a file system. It implements all the interfaces and abstract classes of the new file system and enables access to archive files such as ZIP or JAR, as if they are directories. It is a read-only file system.
Let me begin with description of NIO.2. The new file system NIO.2 has a feature of extensions facility ( through service provider interface ), using which one can develop a file system of their choice by providing concrete implementation to the abstract class java.nio.file.spi.FileSystemProvider. Package all the implementation classes in Java Archive (JAR) file and install ( make available the Jar file in Java class path or copy the Jar file in to JAVA_HOME/jre/lib/ext directory ) it. That's it, your file system is ready, now you can use JSR-203 New File System API's to access your file system. The new API's has many utility methods like java.nio.file.Files.walkFileTree(FileRef start, FileVisitor visitor) using which you can traverse your file system's file tree.
Abstract overview of FileSystemProvider:
File system provider creates file systems using one of the factory methods. A provider can create any number of file systems. For example each archive file is viewed as a file system, provider returns file system instances for each Zip/Jar file. In case of native file systems ( Windows, Solaris, etc. ) provider creates single instance of file system. A file system provides access to file system objects. A file system object can be a file store, file or directory. A file store is nothing but a volume or partition in which files are stored. For example, in Windows platform c:,d:, in Solaris /(root), mounted directories (/home/user) are the file stores. Now lets go over the details of Read-Only Zip Provider:
Let me begin with a brief overview of file system. A file system is formally defined as methods and data structures that an operating system uses to keep track of files on the disk. Data structures are maintained in memory and disk. Operating system provides access methods to access the file system objects. Any container which has organized homogeneous elements can be treated as a file system, provided it has access methods to read these data structures and present information meaningful to the user. Zip/Jar file is one such container. To access a zip file all we need is to define access methods to retrieve/update the properties of file system objects. JSR-203 provides the necessary interfaces and abstract classes i.e. a framework to build any kind of a file system. We just have to provide implementation for these interfaces and abstract classes. NIO.2 comes with default provider which accesses the file system of the host operating system.
File systems can be constructed using one of the factory methods in java.nio.file.FileSystems class. If any of the factory methods is invoked, it iterates over the installed file system providers invoking either the getScheme() (if FileSystems#newFileSystem(URI uri, ...) factory method is used) or newFileSystem( FileRef file, Map<String,?> env ) ( if FileSystems#newFileSystem( FileRef file, Map<String,?> env, ClassLoader loader ) factory method is used ) until either the getScheme() on the provider returns a scheme that matches with the given uri scheme or the newFileSystem(FileRef file, Map<String, ?> env) returns a file system otherwise ProviderNotFoundException is thrown. If the schemes match, then newFileSystem(URI uri, Map<String, ?> env) method will be called on the provider.
Keeping in mind these details let's start the implementation of FileSystemProvider. Name the sub class of FileSystemProvider as ZipFileSystemProvider. Since JSR-203 implementation uses java.util.ServiceLoader for loading the providers and to create an instance of this provider, it is required to have a zero-argument constructor. So, whenever you subclass FileSystemProvider, don't forget to provide a no-argument constructor. FileSystemProvider has two factory methods for creating file systems. >> #newFileSystem(URI uri, Map<String, ?> env) is the abstract method which has to be implemented and it creates a file system identified by the uri. >> The other method is #newFileSystem(FileRef fref, Map<String, ?> env). This method creates file system for an existing file where the file is a container of one or more files. Since Zip File is a container file and it contains many files, we have to provide implementation for this method in ZipFileSystem.
Zip File System is represented by a URI of the form ZIP:///path#pathInZip. The scheme “ZIP” is case insensitive, 'path' locates the zip file in the underlying file system and 'pathInZip' is the path which locates the file inside a Zip/Jar file. For example in uri “ZIP:///c:/java/src.zip#/java/nio/file” , “/java/nio/file” is the path to the entry inside zip “c:/java/src.zip”. All the paths in zip file are relative. So, we can treat Zip File System as a single hierarchical file system where all the paths start with a root “/”. For example, in foo.jar file, paths META-INF/MANIFEST.MF or /META-INF/MANIFEST.MF locates the file MANIFEST.MF. All relative paths are resolved against root “/”. It is a case sensitive file system meaning file paths such as /a/a.file /A/A.file are treated as different files.
In order for this provider to be recognized and loaded when one of the factory methods in java.nio.file.FileSystems is called, we should create a file with name as “java.nio.file.spi.FileSystemProvider” in META-INF/services directory. This file should contain fully qualified name of the class that implements the abstract class FileSystemProvider. So in this case it should be “com.sun.nio.zipfs.ZipFileSystemProvider“.
Since this Zip Provider creates many ZipFileSystems, let us create a table Map<URI, ZipFileSystem> to cache all the created file systems. Here URI is the key and it should not have any fragment component. So URIs of the form “ZIP:///path” is the key that identifies the zip file system.
ZipFileSystemPrvoder#getScheme() returns “ZIP” since the URI that identifies Zip File system should have scheme as “ZIP”.
ZipFileSystemProvider#getPath(URI uri) method searches the cache for the zip file system identified by the given uri. If the scheme of the given uri is not “ZIP” it throws an IllegalArgumentException. If the file system corresponding to the given uri is not available in the cache then it throws FileSystemNotFoundException. If the file system is found in the cache, then method getPath(uri.fragment()) will called on that file system.
ZipFileSystemProvider#newFileSystem(FileRef fref, Map<String, ?> env) is convenient method for creating a file system from an existing file. This method throws an UnsupportedOperationException, if the argument 'fref' does not refer to a path created by the default provider or if the given file is not Zip/Jar file. If the file does not exist, then it throws NoSuchFileException. Otherwise it returns an instance of ZipFileSystem for the given Zip/Jar file. I will discuss how to implement java.nio.file.FileSystem abstract class later part of this blog. One important point to remember here is, we do not cache the file systems created by this method.
ZipFileSystemProvider#newFileSystem(URI uri,Map<String, ?> env) is another method for creating a file system from a uri. The scheme of the given uri should be “ZIP”, otherwise an IllegalArgumentException is thrown. The 'path' component of the uri locates a Zip file in underlying file system, and if the file does not exist NoSuchFileException is thrown. If the file does not end with “.zip” or '.jar” extension then it throws an InvalidPathException. The file systems could be configured using the 'env' argument. User can set the default directory by creating a map with key “default.dir” and a string value which is either home or default directory so that all relative paths will be resolved to this directory. The default directory should be absolute path. If user does not specify default directory then all the relative paths are resolved against root “/”. This method caches the created file system for further reference.
ZipFileSystemProvider#getFileSystem(URI uri) gets the Zip File System instance identified by the given uri from the cache. The key should not contain any fragments. If the given URI contains a fragment component then it is discarded and a new uri is created with the scheme and path. If there is no file system in the cache corresponding to this uri, then FileSystemNotFoundExceptin is thrown. If the scheme of the given uri is not “ZIP” then IllegalArgumentException is thrown.
ZipFileSystemProvider#newFileChannel(Path path, Set<? extends OpenOption> options,Attribute<?>... attrs ) method returns a readable file channel for the given file. This method just converts the given path to string and creates path from default provider and invokes newFileChannel() method on the path. This method should be implemented as FileChennel.open() internally calls the provider's implementation.
Now we will see the implementation of abstract class java.nio.file.FileSystem and name the subclass as ZipFileSystem. Zip file system is read-only, case sensitive and closeable file system. Zip file system like unix, has a single hierarchical directory structure. Each path in zip file system starts with root “/”. The Zip file separator is a forward slash “/”. When you create a Zip or Jar file all the root components (/ in Unix,c:,d: in Windows etc.) in the path are discarded. For example if we create a zip file for all the files in the folder C:\Downloads\* then all the zip file names contain relative paths like Downloads\*. So zip file system resolves all relative paths to root “/” unless environment property “default.dir” is set while creating the file system. If this property is set, then all the relative paths are resolved to the default directory.
This implementation overrides all the the methods with reasonable behavior except the optional FileSystem#newWatchService() method. This method throws UnsupportedOperationException. In other words, Zip file system does not recognize file system notification events.
Zip file system is opened on creation and when closed, closes all the opened Streams and Channels that are opened by this file system and it also removes this file system from the cache which is maintained by the provider. Any attempt to access a closed file system will throw ClosedFileSystemException.
Any operation which access the zip file system acquires read lock and checks whether file system is opened, if closed then throws ClosedFileSystemException, and at the end of operation it releases the read lock. The close method acquires exclusive write lock and releases all the opened resources.
Zip file system provides views to read the file system object properties and methods to get file system objects. One such method is getPath().
ZipFileSystem#getPath() method converts the given string to ZipFilePath object. This method throws an InvalidPathException, if the given string is empty and contains any character that is not valid for naming a file in the underlying file system. If the string contains any backward slashes then they are replaced by Zip file separator ie. “/”.
Zip file system supports three attribute views. A attribute view provides a view into the properties of file system objects. You can get the view of your interest by passing class object of that attribute view to the method FileSystem#newFileAttributeView(Class<?> viewType). The returned attribute view is unbounded. You could bind this attribute view to the file object whose properties needs to be viewed. The attribute views supported by the ZipFileSystem are ZipBasicFileAttributeView, ZipFileAttributeView, and JarFileAttributeView. Description of attribute views are discussed later in this blog.
ZipFileSystem#newFileAttributeView(Class<?> viewType ) returns a requested attribute view. If the requested view type is BasicFileAttributeView, ZipFileAttributeView or JarFileAttributeView then instance of ZipFileBasicAttributeView, ZipFileAttributeView or JarFileAttributeView is returned respectively.
ZipFileSystem#getFileNameMatcher(String syntaxAndPattern) method does the same thing as defined in specification but incase of glob filters it filters the file name against the given case sensitive glob.
Now we will see the implementation of java.nio.file.FileStore. A file store is one which represents storage for files. Since Zip file system has a single hierarchical directory structure on root / and this root is an abstraction for the ZIP or JAR file, the method ZipFileSystem#getFileStores() returns only one file store that gives details of this ZIP or JAR file. ZipFileStore#name() returns the complete path of the ZIP or JAR file, ZipFileStore#type() returns “zipfs” and ZipFileStore#isReadOnly() always returns “true” since this is a read only file system.
ZipFileStore#getFileStoreAttributeViews() returns a list that contains an element ZipFileStoreAttributeView which implements java.nio.file.attribute.FileStoreSpaceAttributeView, so this attribute view is bound to return disk space information for this file store. Since the file store is the ZIP or JAR file, only FileStoreSpaceAttributes#totalSpace() returns the size of the archive file. The other two methods FileStoreSpaceAttributes#{usableSpace, unallocatedSpace}() returns zero since they are not relevant to ZipFileSystem. Another point to be noted about ZipFileStoreAttributeView is , it should provide implementation for the method readAttributes() which returns sub class of FileStoreSpaceAttributes, since it implements FileStoreSpaceAttributeView. Implementation for java.nio.file.Path:
ZipFilePath extends the abstract class java.nio.file.Path, which locates the file or directory in ZIP or JAR. A path in Zip can be relative or absolute. A relative path is resolved against the root if “default.dir” is not provided in the environment configuration map while creating the Zip file system, otherwise it is resolved against the default directory. A path in zip is represented by byte array and it overrides all the methods which handles the components of a path. The methods ZipFilePath#{getName,getNameCount,getFileName,subPath,startsWith,endsWith,getParent}() behave the same way as mentioned in the specification of java.nio.file.Path. In addition to this methods, ZipFilePath has methods getEntryName(), subEntryPath(),getParentEntry(), getEntryName() getEntryNameCount() which deals with entry components of ZipFilePath. Important point to note here is, zip file path can expand to nested zips or jars in the file's path name. For example, /home/userA/zipfile.zip/DirA/dirB/jarFile.jar/META-INF/MANIFEST.MF accesses the jar file “jarFile.jar” inside Zip file “/home/userA/zipfile.zip”. For this path getEntryName(0) returns “/home/userA/zipfile.zip” and getEntryName(1) returns “DirA/DirB/jarFile.jar” getParentEntry() returns “/home/userA/zipfile.zip/DirA/dirB/jarFile.jar” and subEntryPath(0,1) returns “home/userA/zipFile.zip”.
Since ZipFileSystem is read only FileSystem, methods of Path copyTo(..),moveTo(..),createDirectory(..), newOutputStream(..) and delet() throws ReadOnlyFileSystemException, and createSymbolicLink(), createLink()and readSymbolicLink() throws UnsupportedOperationException. Implementation of jav.nio.file.DirectoryStream:
ZipFileStream implements java.nio.file.DirectoryStream, so it has a iterator which iterates entries of a directory in Zip/Jar. ZipFileEntry represents each entry and it implements java.nio.file.DirectoryEntry. When DirectoryStream is opened using the method ZipFilePath#newDirectoryStream(String syntaxAndPattern), it checks for the existence of the file. If the file does not exist, then it throws NoSuchFileException and if the file is not a directory then it throws NotDirctoryException. The remove() method of the iterator that is associated with ZipDirectoryStream throws UnsupportedOperationException with a cause of ReadOnlyFileSystemException. When there are no entries, it just returns empty iterator, otherwise, it returns all the filtered entries in the directory according to given glob or regex pattern. This is similar to iterating entries in the directories in native file system. AttributeViews and Attributes:
Now we will discuss the AttributeViews and Attributes supported by Zip file system. ZipFileSystem supports ZipFileBasicAttributeView, ZipFileAttributeView and JarFileAttributeView. These attribute views provide access to read zip file system object properties. Zip file objects can be a file or directory in a zip/jar. So ZipFileBasicAttribute.readAttributes() returns ZipFileBasicAttributes object which encapsulates the attributes such as size(), modifiedTime() etc.
ZipFileBasicAttributeView implements java.nio.file.attribute.BasicFileAttributeView and it provides implementation for the methods bind(FileRef fref), bind(FileRef,followLinks) and readAttributes().
ZipFileBasicAttributeView#bind(FileRef fref) binds this given FileRef object with this view and bind(FileRef fref, boolean followLinks ) does the same ignoring the followLinks parameter.
The binding facility makes it easier to read the attributes of file system objects. You can get one attribute view and bind it to any of file objects, and retrieve the attributes of the object using readAttributes() method. ZipFileSystem#newFileAttributeView(Class<?> viewType) returns an unbound attribute view, that can be bound to any ZipFilePath object. Rebinding de-references the object to which view was already bound to. Attribute view checks whether file system is opened, if it is closed then ClosedFileSystemException is thrown.
ZipFileBasicAttributes implements java.nio.file.attribute.BasicFileAttrbutes which encapsulates the properties of zip file system object.
ZipFileBasicAttributeView#setTimes(Long lastModifiedTime, Long lastAccessTime, Long createTime, TimeUnit unit) throws ReadOnlyFileSystemException since the ZipFileSystem is read-only.
ZipFileAttributeView extends ZipFileBasicAttributeView which provides a view to zip specific attributes like comment(), compressSize(), crc(), versionMadeBy() etc.
JarFileAttributeView allows user to read Manifest attributes and jar entry attributes.
Lets go over the details of how the Zip provider reads the contents and attributes of zip file entries.
A simple zip file has the following format. [local file header 1] [file data 1] [data descriptor 1] . . . [local file header n] [file data n] [data descriptor n] [central directory] [end of central directory record]
Local file header, central directory and end of central directory record sections are identified by the signatures 0x04034b50,0x02014b50 and 0x06054b50 respectively. Total number of entries and central directory offset are available in “end of central directory record” at the offsets 10 and 16 and number of bytes being 2 and 4 respectively. The byte order of the zip file is little_endian. So you need to set byte order to be LITTLE_ENDIAN when reading the zip file data into ByteBuffer. Once we have number of entries in the zip file, we can read all the file names and attributes of the corresponding file which are available in “central directory” section. Create an object of com.sun.nio.zipfs.ZipEntryInfo or comp.sun.nio.zipfs.JarEntryInfo depending on the archive type and set all the attributes. Cache all these entries in a table. java.util.zip APIs are used only for reading the contents of an entry in zip or Jar file and java.util.jar package methods are used for reading manifest and entry level attributes.
Posted at 03:00PM Mar 13, 2008 by Rajendra Gutupalli in Sun | Comments[2]
Zip File System Provider
Recently I worked on developing a sample code called “ZIP File System Provider”. This sample code demonstrates how to develop a file system using the new Java file system interface ( NIO.2 ). New file system interface is a set of API's which are going to be part of Java SE 7 Platform. These APIs allow us to access the native file system and also provides a service provider interface for pluggable file systems. ZipProvider is one such pluggable file system to the new file system interface. A new file system can be constructed using a factory method . ZipFileSystem provider defines URI of the form ZIP:///path#pathInZip. Here the 'path' is the path to Zip/Jar file which is located in underlying file system and 'pathInZip' locates an entry inside the Zip. I will give more details about the implementation of ZipProvider in my next blog entry. The following code lists the top level directories of the zip file books.zip. Suppose books.zip contains the following files (entries) JavaBooks/RonHichens/JavaNIO.pdf JavaBooks/HerbertSchildt/cr.pdf C_Books/DennisRitchie/c.pdf CtwoPlus/Stroustrap/ctwoplus.pdf ejb5/BillBurke/ejb.pdf general/books/xyz.pdf Then running the following program gives the output: JavaBooks C_Books CtwoPlus ejb5 general
import java.nio.file.*;
import java.net.URI;
import java.util.Map;
import java.util.Collections;
public class ListZipEntries {
public static void main(String[] args) throws Exception {
URI uri = new URI("zip:///C:/zips/books.zip");
Map <String, ?> env = Collections.emptyMap();
FileSystem fs = FileSystems.newFileSystem(uri, env);
// list files in top-level directory of zip file
Path top = fs.getPath("/"); // # line1
DirectoryStream.Filter filter = DirectoryStreamFilters.newCaseSensitiveGlobFilter("*");
Files.withDirectory(top,filter, new DirectoryAction() {
public void invoke(DirectoryEntry entry) {
System.out.println(entry.getFileName());
}
});
}
}
Run this program placing ZIPProvider jar file in the Java class path. ie. java -cp zipfs.jar ListZipEntries.
Modifying the above program by replacing the line1 i.e. “Path path = fs.getPath(“/”)” with “Path path = fs.getPath(“/JavaBooks”);” would result in the following output.
RonHichens
HerbertSchildt
What I am trying to say with this example is, you could traverse the Zip/Jar archive file similar to traversing a directory in the native file system.
Let's assume that we have a Jar file nested inside a Zip. The following program prints the contents of the MANIFEST.MF file which is inside nested jarCompress1.jar file.
import java.io.BufferedInputStream;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Map;
public class ReadEntry {
public static void main(String... args) throws Exception {
Path zipfile = Path.get("c:/zips/zip1.zip");
Map<String, String> env = new HashMap();
FileSystem manager = FileSystems.newFileSystem(zipfile, env,null);
Path path = manager.getPath("/jarCompress1.jar/META-INF/MANIFEST.MF");
System.out.println("Reading input stream");
BufferedInputStream bis = new BufferedInputStream(path.newInputStream());
int ch = -1;
while ((ch = bis.read()) != -1) {
System.out.print((char) ch);
}
}
}
is one more method for creating file systems. This method allows to create a file system from an existing file. In other way, this method allows to view a file as a file system.
Posted at 06:32PM Mar 12, 2008 by Rajendra Gutupalli in Sun | Comments[0]
JSR-203 New Java File System Interface
For the past few months, I have been testing the functionality of new Java file system APIs. These APIs are going to be part of specification JSR-203 (a.k.a. NIO.2). Alan Bateman is the specification lead for this JSR. Testing these new Java API's has been a very fascinating experience for me, as I had to explore the myriad of inputs and scenarios in the file system. NIO.2 is one of the biggest features in Java SE 7. This JSR allows user to develop file systems using the provider interface. Here is the list of some of the features that comes with this JSR. >> Access to file system attributes(owner,etc.) >> Support for file system change notifications >> create and modify Access Control Lists (ACL's) >> Gracefully handle file system failures >> Service provider interface for pluggable file systems. >> Utility methods for file system activities(copy, move, walkFileTree etc.) >> dealing with links (creating, deleting and following links) >> incremental listing of files in the directory. >> and many more ...
I would like to give examples which interest you in the coming entries of this blog.Posted at 04:26PM Mar 12, 2008 by Rajendra Gutupalli in Sun | Comments[6]