Tuesday, September 11, 2007

Java FAQ's

1. Can there be an abstract class with no abstract methods in it?
- Yes

2. Can an Interface be final?
- No

3. Can an Interface have an inner class?
- Yes.

public interface abc
{
static int i=0; void dd();
class a1
{
a1()
{
int j;
System.out.println("inside");
};
public static void main(String a1[])
{
System.out.println("in interfia");
}
}
}

4. Can we define private and protected modifiers for variables in interfaces?
- No

5. What is Externalizable? -
Externalizable is an Interface that extends Serializable Interface. And sends data into Streams in Compressed Format. It has two methods, writeExternal(ObjectOuput out) and readExternal(ObjectInput in)

6. What modifiers are allowed for methods in an Interface?
- Only public and abstract modifiers are allowed for methods in interfaces.

7. What is a local, member and a class variable?
- Variables declared within a method are “local” variables. Variables declared within the class i.e not within any methods are “member” variables (global variables). Variables declared within the class i.e not within any methods and are defined as “static” are class variables

8. What are the different identifier states of a Thread?
- The different identifiers of a Thread are: R - Running or runnable thread, S - Suspended thread, CW - Thread waiting on a condition variable, MW - Thread waiting on a monitor lock, MS - Thread suspended waiting on a monitor lock

9. What are some alternatives to inheritance?
- Delegation is an alternative to inheritance. Delegation means that you include an instance of another class as an instance variable, and forward messages to the instance. It is often safer than inheritance because it forces you to think about each message you forward, because the instance is of a known class, rather than a new class, and because it doesn’t force you to accept all the methods of the super class: you can provide only the methods that really make sense. On the other hand, it makes you write more code, and it is harder to re-use (because it is not a subclass).

10. Why isn’t there operator overloading?
- Because C++ has proven by example that operator overloading makes code almost impossible to maintain. In fact there very nearly wasn’t even method overloading in Java, but it was thought that this was too useful for some very basic methods like print(). Note that some of the classes like DataOutputStream have unoverloaded methods like writeInt() and writeByte().

11. What does it mean that a method or field is “static”?
- Static variables and methods are instantiated only once per class. In other words they are class variables, not instance variables. If you change the value of a static variable in a particular object, the value of that variable changes for all instances of that class. Static methods can be referenced with the name of the class rather than the name of a particular object of the class (though that works too). That’s how library methods like System.out.println() work. out is a static field in the java.lang.System class.

12. How do I convert a numeric IP address like 192.18.97.39 into a hostname like java.sun.com?

String hostname = InetAddress.getByName("192.18.97.39").getHostName();

13. Difference between JRE/JVM/JDK?

14. Why do threads block on I/O?
- Threads block on i/o (that is enters the waiting state) so that other threads may execute while the I/O operation is performed.

15. What is synchronization and why is it important?
- With respect to multithreading, synchronization is the capability to control the access of multiple threads to shared resources. Without synchronization, it is possible for one thread to modify a shared object while another thread is in the process of using or updating that object’s value. This often leads to significant errors.

16. Is null a keyword?
- The null value is not a keyword.

17. Which characters may be used as the second character of an identifier,but not as the first character of an identifier?
- The digits 0 through 9 may not be used as the first character of an identifier but they may be used after the first character of an identifier.

18. What modifiers may be used with an inner class that is a member of an outer class?
- A (non-local) inner class may be declared as public, protected, private, static, final, or abstract.

19. How many bits are used to represent Unicode, ASCII, UTF-16, and UTF-8 characters?
- Unicode requires 16 bits and ASCII require 7 bits. Although the ASCII character set uses only 7 bits, it is usually represented as 8 bits. UTF-8 represents characters using 8, 16, and 18 bit patterns. UTF-16 uses 16-bit and larger bit patterns.

20. What are wrapped classes?
- Wrapped classes are classes that allow primitive types to be accessed as objects.

21. What restrictions are placed on the location of a package statement within a source code file?
- A package statement must appear as the first line in a source code file (excluding blank lines and comments).

22. What is the difference between preemptive scheduling and time slicing?
- Under preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a higher priority task comes into existence. Under time slicing, a task executes for a predefined slice of time and then reenters the pool of ready tasks. The scheduler then determines which task should execute next, based on priority and other factors.

23. What is a native method?
- A native method is a method that is implemented in a language other than Java.

24. What are order of precedence and associativity, and how are they used?
- Order of precedence determines the order in which operators are evaluated in expressions. Associatity determines whether an expression is evaluated left-to-right or right-to-left

25. What is the catch or declare rule for method declarations?
- If a checked exception may be thrown within the body of a method, the method must either catch the exception or declare it in its throws clause.

26. Can an anonymous class be declared as implementing an interface and extending a class?
- An anonymous class may implement an interface or extend a superclass, but may not be declared to do both.

27. What is the range of the char type?
- The range of the char type is 0 to 2^16 - 1.

Thursday, September 6, 2007

How to Access Cookies Set at the Client Side

Class javax.servlet.http.cookies can be used to access cookies on the client side. The following code demonstrates this technique. The code also checks for the cookie names in order to access the desired one.


boolean bcookiefound = false;
Cookie[] cookies = request.getCookies();
for(int nIndex=0;nIndex <cookies.length;nIndex++)
{
if(cookies[nIndex].getName().equals(“MyCookie”))
{
bcookiefound = true;
//desired cookie found, use it
}
}
if(bcookiefound == false)
{
//cookie not found.
}

Look Up a Bean Interface in EJB 3.0

In principle, in EJB 3.0, you can access a bean from another bean by looking it up in the interface (local or remote). Here are two solutions for doing that:

1. Through the JNDI, you still have the portability:


//get the default JNDI initial context
Context ctx=new InitialContext();
//get the bussiness interface
Object obj=ctx.lookup(BusinessInterface.class.getName());
//convert obj
BusinessInterface bi=(BusinessInterface)obj;

2. Through the @EJB annotiation:


@EJB BusinessInterface bi; //cooool !

Spring 2.1 Grows New Features and Evolutionary Enhancements

In this article, I will look at the latest and upcoming releases of the Spring Java framework. In one of my previous articles, "Spring: the Eclectic Framework," I discussed the Spring application framework. But since then, Interface21, the company responsible for development and support of the framework, implemented many new features and has released version 2.0 of Spring. The upcoming preview edition 2.1 is already underway, and I will discuss what has changed and improved in this new version over the previous one. Because the Spring framework is an aggregation of various components and modules, its parts have evolved differently, but overall version 2.1 is a major improvement over version 1.x and a sizable improvement over 2.0.

It's good to see that these changes are evolutionary, rather then revolutionary, and are inline with the development trends in the Java community. Among the new enhancements are: support for the Java SE 6 features, integration with JSF, enhancements in the Aspect Oriented Programming (AOP) framework, greater Java Annotations support, more configuration, and bean wiring options (now with Java annotations in addition to XML), as well as a refinement of module for web flow management called Web Flow 1.1. Additionally, Spring 2.1 introduces Portlet MVC framework, integration with Java Persistence API (JPA), and the ability for Spring beans to be implemented in dynamic languages, such as Groovy, JRuby, and Beanshell. There are also further improvements to the core components of Spring—IoC container and Dependency Injection mechanism.
Java Annotations and Spring

Since Java version 1, there were always ways to define specific language behavior using tag metadata. As of Java 5, developers can create custom metadata tags and put them in the code to achieve certain behavior. These custom tags are called annotations. For example, there are three metadata types that are predefined by the Java language specification itself: @Deprecated, @Override, and @SuppressWarnings. An annotation is a special kind of modifier, and can be implemented in situations where other modifiers, such as public, static, or final are used. Annotations can be declared with no value or one or more parameters.

For example, a new annotation can be declared like this:

public @interface Copyright {}

or like this

public @interface Copyright { int yr(); }

and then used with in source code like this:

@Copyright public class Vlad { ... }

Or

@Copyright(2007) public class Vlad { ... }

The definition of annotations is similar to the Java Interface definition, but each method declaration defines an element of the annotation type. Method declarations must not have any parameters or a throws clause. In addition, all return types are restricted to primitives, String, Class, enums, annotations, or arrays of these types.

By definition, annotations have no direct effect on the operation of the code they annotate. So what good do they do? Their usefulness is in their ability to affect the semantics of the running program. This means that they are commands to the compiler (or other tools and libraries) to do something special with the code. For example, the default annotation @SuppressWarnings tells the Jave compiler to ignore and not show any warnings generated by the code annotated by this tag. Similarly, the @deprecated tag indicates that the method marked with it will not be supported in the future, and the compiler needs to generate an appropriate message to the developer.

Spring had some annotations in its early version, but added many more in version 2.0 and even more in version 2.1. Version 1.2 introduced the @Transactional and @ManagedResource tags (for JMX management). Also, the new version adds tags such as, @Configurable, @Required, and @Repository, among others. New annotations within Spring's Aspect Oriented Programming (AOP) are also used to express pointcuts and advices.

I have barely scratched the surface of the annotations because the purpose of this article is to provide an overview. However, if you are interested in gaining more detailed understanding of annotations, I suggest looking at the AspectJ 5 language.
Spring Configuration

The current process of configuring the Spring components is largely done with the XML configuration files. Without proper tools, novice developers may face a steep learning curve when challenged with the task of Spring component configuration and bean "wiring" for the IoC processes. Luckily, more IDEs are coming out to help with configuration task and I will talk about some of them later in this article.

The upcoming 2.1 release will introduce more ways to configure Spring components through annotations in the source code. What this means is that, in addition to the old way of configuring Spring with plain XML, developers will be able to annotate their classes (or beans) with special tags to achieve the same effect. It also will be necessary for the tools' vendors to implement support for this feature so that developers can get the full benefit.
The Spring Web Flow 1.1 Module

Even though Spring is considered a Java web framework, there is really not much in core Spring that would help web developers create web applications. Most of the Spring modules deal with simplification of non-visual aspects or back-end processes of Java programming, such as Inversion of Control, Aspect Oriented Programming, JDBC connections, exception handling, and so forth.

Therefore, it is not surprising that the developers of Spring introduced a separate module dealing primarily with web application flow management. This module is called Spring Web Flow, and is designed to be a framework for web application navigation (not to be confused with MVC). Spring Web Flow is similar in functionality to any modern web framework, such as Struts or Web Work, but different in its packaging. In fact, Spring Web Flow can be integrated with Struts and Java Server Faces (JSF). And, version 1.1 of Web Flow actually has specific features for tighter integration with JSF.

With Web Flow, developers can "set" or create a series of steps based on use-cases, and tie them in easily with the other Spring modules on the back end, or with JSF on the front -end. The flows can be separated into reusable modules, chained as sub-flows, tested in isolation, and deployed to different target containers (such as Servlet or Portlet containers).

Here is an example of a Spring flow:

Figure 1: Spring Web flow diagram

Flows are described using XML, and once created, do not need to be changed when the environment executing them changes. For example, same flow definition should work in the Servlet container and with JUnit, Spring MVC, or Struts. Because flows are configuration based, the Spring IDE includes support for editing and visualizing them graphically. (See more about IDE support later in the article.)

Additionally, here are some more features of the Spring Web Flow module:

* Automatic garbage collection of memory allocated during flow execution
* Changes to navigation rules do not require container restart
* Automatic browser button support (back, forward, refresh)

Both Spring and Spring Web Flow are released under the Apache license.

Spring IDE Tools

The Spring framework has gained enough momentum in the enterprise developer market that heavy-weight IDE vendors are starting to take notice and incorporate support for Spring into their products. This, in turn, can serve as a snowball effect and introduce Spring to more developers. Oracle Corporation has recently released an extension to its flagship JDeveloper IDE that will incorporate a Spring framework-based SDK, and include support for Spring 1.x and 2.0. The Oracle IDE will help developers by providing auto-complete, code insight, and XML validation of Spring definitions.

Figure 2: Oracle JDeveloper 10g screen shot

The folks who developed the original Spring IDE also just released the final version of Spring IDE 2.0. The Spring IDE is a plug-in for the Eclipse IDE and Eclipse 3.2.x (or newer) is required to run Spring IDE 2.0. The new IDE is a huge improvement over version 1.x. It adds support for Spring 2.0, Spring Web Flow, Spring AOP and Spring JavaConfig and, according to its web site—Spring IDE 2.0 also eliminates approximately 250 bugs.

Figure 3: Spring IDE Screen Shot

Because in the past the only IDE available was the Spring IDE 1.x (which seems to have been very buggy according to its own web site), developers who did not want to write tons of Spring configuration XML code by hand, or deal with remembering and typing overly long Spring class names, tried not to use the technology if they did not have to. The enterprise tool support is very good news for the Spring framework and the developers using it. The development of the solid IDEs for the Spring framework, such as JDeveloper and substantial improvement in original Spring IDE, means that working with the framework will be much easier and the learning curve may decrease.
Conclusion

In this article, I discussed new features of the Spring framework 2.0 and 2.1, such as annotations, web flow, and so on. I also mentioned new IDE vendor support for Spring. It will be interesting to see what other IDEs with jump onboard with Spring support, what new features will grow in the Spring framework, and whether the adoption of Spring increases.
References

* Java Annotations: http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
* Spring 2.0: What's New and Why it Matters: http://www.infoq.com/articles/spring-2-intro
* Interface21: Springframework.org
* SpringIDE: http://springide.org/project/wiki/TOC
http://springide.org/project/wiki/SpringideInstall

Wednesday, September 5, 2007

Read and write data with Java's I/O streams

All of Java's I/O is based upon streams. Once you learn the syntax for one stream; you can work with any other type in Java. This article introduces some ways of working with Java streams.

The Java input/output (I/O) facilities provide a simple, standardised API for reading and writing character and byte data from various data sources. In this article, we'll explore the I/O classes, interfaces, and operations provided by the Java platform. Let's start by taking a look at Java streams.

Streams

All of Java's I/O facilities are based on streams that represent flowing sequences of characters or bytes. Java's I/O streams provide standardised ways to read and write data. Any object representing a mutable data source in Java exposes methods for reading and writing its data as a stream.

Java.io is the main package for most stream-oriented I/O classes. This package presents two abstract classes, InputStream and OutputStream. All other stream-oriented I/O classes extend these base classes.

The java.io package exposes a number of classes and interfaces that provide useful abstractions on top of the character and byte reading and writing operations defined by InputStream and OutputStream. For example, the ObjectInputStream class provides methods that allow you to read data from a stream as a Java object, and the ObjectOutputStream provides methods that allow you to write data to a stream as a Java object.

Optimised reading and writing

JDK 1.1 added a collection of reader and writer classes that provide more useful abstractions and improved I/O performance than the existing streams classes. For instance, the BufferedReader and BufferedWriter classes are provided to read text from and write text to character-based input streams and output streams. The BufferedReader class buffers characters to more efficiently read characters, arrays, and lines. The BufferedWriter class buffers characters to more efficiently write characters, arrays, and strings. The size of the buffer used by the BufferedReader and BufferedWriter classes can be set as desired.

Reader and writer classes provided by the Java I/O Framework include the LineNumberReader class, the CharArrayReader class, the FileReader class, the FilterReader class, the PushbackReader class, the PipedReader class, and the StringReader class, among others. These classes are wrappers on top of the InputStream and OutputStream classes and thus provide methods that are similar to InputStream and OutputStream. However, these classes provide more efficient and useful abstractions for reading and writing specific objects, such as files, character arrays, and strings.

Reading data

An input stream is typically opened for you automatically when it is retrieved from the corresponding data source object or when you construct one of the reader objects. For example, to open the input stream for a file, we pass the name of the file into a java.io.FileReader object's constructor as follows:

java.io.FileReader fileReader = new java.io.FileReader("/home/me/myfile.txt");

To read the next available byte of data from a FileReader's underlying input stream, use the read method with no parameters. The snippet in Listing A reads text from a file, one character at a time, and writes it to System.out.

Listing A

int aChar = 0;
while ((aChar = fileReader.read()) >= 0)
{
System.out.print((char)aChar);
}

To read a given number of bytes from an input stream into a char array, use the read method with one char[] parameter. The length of the array is used to determine the number of characters to read. Listing B demonstrates this technique.

Listing B

char[] buffer = new char[256];
while ((fileReader.read(buffer)) >= 0)
{
System.out.print(new String(buffer));
}

To close an input stream and release any system resources used by the stream, use the close method as follows:

fileReader.close();

Writing data

Like an input stream, an output stream is typically opened for you automatically when it is retrieved from the corresponding data source object or when you construct one of the writer objects. For example, to open the output stream for a file, we pass the name of the file into a java.io.FileWriter object's constructor as follows:

java.io.FileWriter fileWriter = new java.io.FileWriter("/home/me/out.txt");

To write one specified character to an output stream, use the write method with one int parameter. The int parameter represents the character to write.

int aChar = (int)'X';

fileWriter.write(aChar);

To write a specific number of bytes from a specified char array starting at a given offset to an output stream, use the write method with a char[] parameter, an int offset parameter, and an int length parameter as shown in the following example:

fileWriter.write(buffer, 0, byteCount);

To close an output stream and release any system resources associated with the stream, use the close method, like this:

fileWriter.close();

To force any buffered data out of an output stream, use the flush method as follows:

fileWriter.flush();

Putting it all together

We can use what we have learned to read from one file and simultaneously write to another, as demonstrated in Listing C.

Listing C

try
{
java.io.FileReader fileReader =
new java.io.FileReader("/home/me/temp.txt");
java.io.FileWriter fileWriter =
new java.io.FileWriter("/home/me/out.txt");
char[] buffer = new char[256];
int byteCount = 0;
while ((byteCount = fileReader.read(buffer)) >= 0)
{
fileWriter.write(buffer, 0, byteCount);
}
fileWriter.flush();
fileWriter.close();
fileReader.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}

Summary

The Java I/O facilities add a simple and standardised API for reading and writing character and byte data from various data sources. Experience obtained while working with Java streams for one type of data source can be carried over to any other type of data source exposed by Java.

Tuesday, September 4, 2007

Determine the available memory in Java

Java Memory Allocation
The following example shows how much memory that JVM has allocated for your application:

Runtime runtime = Runtime.getRuntime();
System.out.println("allocated memory: " + runtime.totalMemory() / 1024);

The totalMemory() method returns the amount of memory the JVM has allocated from the operating system. Unless you specified the amount of memory to allocate using the -Xms command line option, the totalMemory() method will continually fluctuate as objects are allocated and the garbage collection cleans them up.

The following example shows how to discover how much memory is being used by your application:

Runtime runtime = Runtime.getRuntime();
System.out.println("free memory: " + runtime.freeMemory() / 1024);

The freeMemory() method will return the amount of free memory from the allocated memory. Since this value does not include any memory that hasn't yet been allocated by the JVM, you will need to get a complete picture of the free memory that your application would be able to use. To do this, you need to include the amount of memory that hasn't yet bee allocated by the JVM, but could be allocated if necessary. The following example shows how:

Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
System.out.println("free memory: " + freeMemory / 1024);
System.out.println("allocated memory: " + allocatedMemory / 1024);
System.out.println("max memory: " + maxMemory / 1024);
System.out.println("total free memory: " + (freeMemory + (maxMemory - allocatedMemory)) / 1024);

Sample results from the test below show that Java only allocated a small amount of memory and a large amount of memory is still available to the application:

free memory: 294
total memory: 1984
max memory: 65088
total free memory: 63398

Singleton

Java has several design patterns Singleton Pattern being the most commonly used design pattern. Java Singleton pattern belongs to the family of design patterns, that govern the instantiation process. This design pattern proposes that at any time there can only be one instance of a singleton (object) created by the JVM.

The Singleton class’s default constructor is made private, which prevents the direct instantiation of the object by others (Other Classes). A static modifier is applied to the instance method that returns the singleton object as it then makes this method a class level method that can be accessed without creating an object.

One such scenario where it might prove useful is when we develop the Java Help Module in a project. Java Help is an extensible, platform-independent help system that enables authors and developers to incorporate online help into applications. Since at any time we can do only with one main Help object and use the same object in different screens, Singleton Pattern suits best for its implementation.

A singleton pattern can also be used to create a Connection Pool. If programmers create a new connection object in every java class that requires it, then its clear waste of resources. In this scenario by using a singleton connection class we can maintain a single connection object which can be used throughout the Java application.

Implementing the Singleton Pattern

To implement this design pattern we need to consider the following 4 steps:

Step 1: Provide a default Private constructor


public class SingletonObjectDemo
{
//Note that the constructor is private
private SingletonObjectDemo ()
{
// Optional Code
}
}



Step 2: Create a Method for getting the reference to the Singleton Object

public class SingletonObjectDemo{
private static SingletonObject singletonObject;

//Note that the constructor is private
private SingletonObjectDemo (){
// Optional Code
}

public static SingletonObjectDemo getSingletonObject(){
if (singletonObject == null){
singletonObject = new SingletonObjectDemo ();
}
return singletonObject;

}

}

We write a public static getter or access method to get the instance of the Singleton Object at runtime. First time the object is created inside this method as it is null. Subsequent calls to this method returns the same object created as the object is globally declared (private) and the hence the same referenced object is returned.

Step 3: Make the Access method Synchronized to prevent Thread Problems.

public static synchronized SingletonObjectDemo getSingletonObject()

It could happen that the access method may be called twice from 2 different classes at the same time and hence more than one singleton object being created. This could violate singleton pattern principle. In order to prevent the simultaneous invocation of the getter method by 2 threads or classes simultaneously we add the synchronized keyword to the method declaration

Step 4: Override the Object clone method to prevent cloning.

We can still be able to create a copy of the Object by cloning it using the Object’s clone method. This can be done as shown below

SingletonObjectDemo clonedObject = (SingletonObjectDemo) obj.clone();

This again violates the Singleton Design Pattern's objective. So to deal with this we need to override the Object’s clone method which throws a CloneNotSupportedException exception.

public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}



The below program shows the final Implementation of Singleton Design Pattern in java, by using all the 4 steps mentioned above.

class SingletonClass{

private static SingletonClass singletonObject;

/** A private Constructor prevents any other class from instantiating. */
private SingletonClass(){
// Optional Code
}

public static synchronized SingletonClass getSingletonObject()
{
if (singletonObject == null){
singletonObject = new SingletonClass();
}
return singletonObject;
}

public Object clone()throws CloneNotSupportedException
{
throw new CloneNotSupportedException();
}

}

public class SingletonObjectDemo{
public static void main(String args[]){
// SingletonClass obj = new SingletonClass(); Compilation error not allowed

//create the Singleton Object..
SingletonClass obj = SingletonClass.getSingletonObject();

// Your Business Logic
System.out.println("Singleton object obtained");

}
}

Another approach to using Singleton pattern

We don't need to do a lazy initialization of the instance object or to check for null in the get method. We can also make the singleton class final to avoid sub classing of singletons that may cause other problems.

public class SingletonClass {
private static SingletonClass ourInstance = new SingletonClass();
public static SingletonClass getInstance() {
return singletonObj; }
private SingletonClass() {
}
}



In Summary, the job of the Singleton class is to enforce the existence of a maximum of one object of the same type at any given time. Depending on your implementation, your Singleton class and all of its data might be garbage collected. Hence we must ensure that at any point there must be a live reference to the Singleton class when the application is running.

Saturday, September 1, 2007

Open Source JSP Tag Library provides Java Front-End to GoogleMaps API

Google:maps - a freeware, open-source project to provide a 100% Java front-end to the GoogleMaps API - is a JSP taglibrary that provides cross-browser and clean GoogleMaps output, every time, according to the enthusiasts behind the project.

Led by Tom E. Cole, whose day job is as general manager of Lamatek, Inc., the group says that the Tag Library provides JSP developers with the ability to create fully functional Google Maps with absolutely no JavaScript or AJAX programming.

"I like JSP technology," Cole explains, "and I like GoogleMaps. To me it was a perfect match, creating an industry standard front-end to a leading edge technology, making it available to many developers without the burden of learning a whole new API or to many even a whole new programming language."

"It goes beyond the standard API by providing complete 100% Java event handling, either synchronously or asynchronously, includes advanced overlays like circles, polygons, boxes and the ability to hook the mousewheel into the zoom function," notes Cole.

He adds: "The taglibrary has been fully tested on all IE, Firefox, Netscape and Opera browsers supported by GoogleMaps to ensure consistent, cross-browser functionality. Using the Google Maps JSP Taglibrary you'll never see that 'it works in Firefox, but not IE' problem ever again."

Cole is quick to offer full credit two fellow developers: "Joaquin Cuenca Abela was kind enough to offer the Javascript code that maps the mousewheel to the zoom function; Kapil at tripmojo.com provided the Javascript function for drawing circles."

Developers can incorporate Google Maps JSP Taglibrary with JSTL and its own built in event handling capabilities to create fully interactive 2-way mapping applications, Cole explains.

LINK:http://www.lamatek.com/GoogleMaps/