Monday, January 2, 2017

Java Interview Questions - Svam International & Home Shop 18

Asked in Svam International for US Onsite position & home shop 18:


1) Can we use restful webservice along with spring MVC directly?
Yes we have to use spring boot. For example:
@RestController
@RequestMapping("/tct-pw/admin")
public class UserRoleController {

private static final Logger logger = LoggerFactory.getLogger(UserRoleController.class);

@Autowired
UserRoleService usrRoleService;


@RequestMapping(value="/getuserrole",method = RequestMethod.GET)
public @ResponseBody
Map<String,Map<String,List<String>>> getUserRoleList(@RequestParam("sso") String sso) {
List<String> lstAvailableRoles = new ArrayList<String>();
List<String> lstAssignedRoles = new ArrayList<String>();
Map<String,List<String>> mpRoles = new HashMap<String,List<String>>();
Map<String,Map<String,List<String>>> result = new HashMap<String,Map<String,List<String>>>();

lstAvailableRoles = usrRoleService.getAvailableRoleList(sso);
lstAssignedRoles = usrRoleService.getAssignedRoleList(sso);
mpRoles.put(AppConstant.AVAILABLE_ROLE, lstAvailableRoles);
mpRoles.put(AppConstant.ASSIGNED_ROLE, lstAssignedRoles);
result.put(AppConstant.RESULTS,mpRoles);

return result;

}
3) Exception Example:
Will it be compiled:
package p1;

import java.io.IOException;

public class Sample
{

       public void methodA() throws IOException
       {
             
       }
}
class B extends Sample
{
      
       public void methodA() throws Exception
       {
             
       }
      
}
Ans: no, it will not be compiled. Because up casting is not allowed here, but vice versa is fine.
In case of unchecked exception it is allowed. If we ignore throws in subclass then also it is fine.
5) What are generics, have you worked on it, have you created your own generics. What is the benefit of generics?
Ans:
Generic method example:
public class GenericMethodTest {
       // generic method printArray
       public static <E> void printArray(E[] inputArray) {
              // Display array elements
              for (E element : inputArray) {
                     System.out.printf("%s ", element);
              }
              System.out.println();
       }

       public static void main(String args[]) {
              // Create arrays of Integer, Double and Character
              Integer[] intArray = { 1, 2, 3, 4, 5 };
              Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
              Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

              System.out.println("Array integerArray contains:");
              printMyArray(intArray); // pass an Integer array

              System.out.println("\nArray doubleArray contains:");
              printMyArray(doubleArray); // pass a Double array

              System.out.println("\nArray characterArray contains:");
              printMyArray(charArray); // pass a Character array
       }
       public static <MY> void printMyArray(MY[] m)
       {
              for(MY e:m)
              {
                     System.out.print(e + " ");
              }
              System.out.println();
       }
}
Bounded type parameter example:
public class MaximumTest
{
   // determines the largest of three Comparable objects
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // assume x is initially the largest      
      if ( y.compareTo( max ) > 0 ){
         max = y; // y is the largest so far
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // z is the largest now                
      }
      return max; // returns the largest object  
   }
  
   public static void main( String args[] )
   {
      System.out.printf( "Max of %d, %d and %d is %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );

      System.out.printf( "Maxm of %.1f,%.1f and %.1f is %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );

      System.out.printf( "Max of %s, %s and %s is %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}
Generic  class example:
public class Box<T> {
 
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
     Box<Integer> integerBox = new Box<Integer>();
     Box<String> stringBox = new Box<String>();
    
     integerBox.add(new Integer(10));
     stringBox.add(new String("Hello World"));
 
     System.out.printf("Integer Value :%d\n\n", integerBox.get());
     System.out.printf("String Value :%s\n", stringBox.get());
  }
}

6) What is the difference between ConcurrentHashMap and HashMap?
ConcurrentHashMap in Java is introduced as an alternative of Hashtable in Java, which is a synchronized collection class, that makes the main difference between HashMap and ConcurrentHashMapwhich is one is non synchronized , non thread safe and not for use in Concurrent multi-threaded environment while ...

ConcurrentHashMap

·         You should use ConcurrentHashMap when you need very high concurrency in your project.
·         It is thread safe without synchronizing the whole map.
  • Reads can happen very fast while write is done with a lock.
  • There is no locking at the object level.
  • The locking is at a much finer granularity at a hashmap bucket level.
  • ConcurrentHashMap doesn’t throw a ConcurrentModificationException if one thread tries to modify it while another is iterating over it.
  • ConcurrentHashMap uses multitude of locks.

SynchronizedHashMap

·         Synchronization at Object level.
·         Every read/write operation needs to acquire lock.
·         Locking the entire collection is a performance overhead.
·         This essentially gives access to only one thread to the entire map & blocks all the other threads.
·         It may cause contention.
·         SynchronizedHashMap returns Iterator, which fails-fast on concurrent modification.

9) What is the benefit of using annotations, have you created your own annotations. How it works internally.
Ans: Benefits:
Annotations have a lot of advantages over XML, to name a few :
·         Static type checking - the compiler will check for you where the annotation (once defined properly) is applicable and how
·         Clean code - its much easier to see (visually) the meta data defined in annotations
Disadvantage:
·         XML doesn't require recompilation when you want to change something. With annotation you'll have to recompile.

Refer page no 4 in HCL questions answer.
10) What are all annotations you have used in restful webservice.
Ans:
@ApplicationPath annotation is used to define the base URI of the resource in rest implementation.
@ApplicationPath("/rest") – works as an application path (root) for rest ws.
@RequestScoped: An object which is defined as @RequestScoped is created once for every request and is shared by all the bean that inject it throughout a request.
@Path – The @Path annotation identifies the URI path template to which the resource responds, and is specified at the class level of a resource.
@Path("/users/{username}")
In this type of example, a user will be prompted to enter their name, and then a Jersey web service configured to respond to requests to this URI path template will respond. For example, if the user entered their user name as Galileo, the web service will respond to the following URL:
http://example.com/users/Galileo
To obtain the value of the username variable, the @PathParamannotation may be used on the method parameter of a request method, as shown in the following code example.
@Path("/users/{username}")
public class UserResource {
 
    @GET
    @Produces("text/xml")
    public String getUser(@PathParam("username") String userName) {
        ...
    }
}
@POST
@GET
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.TEXT_PLAIN)
                The @Consumes annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client. If@Consumes is applied at the class level, all the response methods accept the specified MIME types by default. If @Consumes is applied at the method level, it overrides any @Consumes annotations applied at the class level.
If a resource is unable to consume the MIME type of a client request, the Jersey runtime sends back an HTTP “415 Unsupported Media Type” error.
The value of @Consumes is an array of String of acceptable MIME types. For example:
@Consumes({"text/plain,text/html"})
The following example shows how to apply @Consumes at both the class and method levels:
@Path("/myResource")
@Consumes("multipart/related")
public class SomeResource {
       @POST
       public String doPost(MimeMultipart mimeMultipartData) {
               ...
       }
 
       @POST
       @Consumes("application/x-www-form-urlencoded")
       public String doPost2(FormURLEncodedProperties formData) {
               ...
       }
}
The doPost method defaults to the MIME media type of the @Consumes annotation at the class level. The doPost2 method overrides the class level @Consumes annotation to specify that it can accept URL-encoded form data.
If no resource methods can respond to the requested MIME type, an HTTP 415 error (Unsupported Media Type) is returned to the client.
The HelloWorld example discussed previously in this section can be modified to set the cliched message using @Consumes, as shown in the following code example.
@POST
@Consumes("text/plain")
public void postClichedMessage(String message) {
    // Store the message
}
In this example, the Java method will consume representations identified by the MIME media type text/plain. Notice that the resource method returns void. This means no representation is returned and response with a status code of HTTP 204 (No Content) will be returned.

@FormParam("suppCodeDown") String suppCode
@QueryParam("suppCodeDown") String suppCode
@PathParam("username") String username
@Inject
16) How HashMaps works internally.What is Hashing?
Hashing in its simplest form, is a way to assigning a unique code for any variable/object after applying any formula/algorithm on its properties. A true Hashing function must follow this rule:

Hash function should return the same hash code each and every time, when function is applied on same or equal objects. In other words, two equal objects must produce same hash code consistently.


Note: All objects in java inherit a default implementation of hashCode() function defined in Object class. This function produce hash code by typically converting the internal address of the object into an integer, thus producing different hash codes for all different objects.
HashMap is an array of Entry objects:
Consider HashMap as just an array of objects.

Have a look what this Object is:
1.       static class Entry<K,V> implements Map.Entry<K,V> {  
2.               final K key;  
3.               V value;  
4.               Entry<K,V> next;  
5.               final int hash;  
6.       ...   
7.       }  

Each Entry object represents key-value pair. Field next refers to other Entry object if a bucket has more than 1 Entry.

Sometimes it might happen that hashCodes for 2 different objects are the same. In this case 2 objects will be saved in one bucket and will be presented as LinkedList. The entry point is more recently added object. This object refers to other object with next field and so one. Last entry refers to null.

When you create HashMap with default constructor
1.       HashMap hashMap = new HashMap();  
Array is gets created with size 16 and default 0.75 load balance.


Adding a new key-value pair
1.  Calculate hashcode for the key
2.  Calculate position hash % (arrayLength-1)) where element should be placed(bucket number)
3.  If you try to add a value with a key which has already been saved in HashMap, then value gets overwritten.
4.  Otherwise element is added to the bucket. If bucket has already at least one element - a new one is gets added and placed in the first position in the bucket. Its next field refers to the old element.
Deletion:
1.  Calculate hashcode for the given key
2.  Calculate bucket number (hash % (arrayLength-1))
3.  Get a reference to the first Entry object in the bucket and by means of equals method iterate over all entries in the given bucket. Eventually we will find correct Entry. If desired element is not found - return null
What put() method actually does:
Before going into put() method’s implementation, it is very important to learn that instances of Entry class are stored in an array.HashMap class defines this variable as:
1.       /** 
2.            * The table, resized as necessary. Length MUST Always be a power of two. 
3.            */  
4.           transient Entry[] table;  
Now look at code implementation of put() method:
1.       /** 
2.         * Associates the specified value with the specified key in this map. If the 
3.         * map previously contained a mapping for the key, the old value is 
4.         * replaced. 
5.         * 
6.         * @param key 
7.         *            key with which the specified value is to be associated 
8.         * @param value 
9.         *            value to be associated with the specified key 
10.        * @return the previous value associated with <tt>key</tt>, or <tt>null</tt> 
11.        *         if there was no mapping for <tt>key</tt>. (A <tt>null</tt> return 
12.        *         can also indicate that the map previously associated 
13.        *         <tt>null</tt> with <tt>key</tt>.) 
14.        */  
15.       public V put(K key, V value) {  
16.        if (key == null)  
17.         return putForNullKey(value);  
18.        int hash = hash(key.hashCode());  
19.        int i = indexFor(hash, table.length);  
20.        for (Entry<k , V> e = table[i]; e != null; e = e.next) {  
21.         Object k;  
22.         if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
23.          V oldValue = e.value;  
24.          e.value = value;  
25.          e.recordAccess(this);  
26.          return oldValue;  
27.         }  
28.        }  
29.        
30.        modCount++;  
31.        addEntry(hash, key, value, i);  
32.        return null;  
33.       }  

Lets note down the steps one by one:

Step1- First of all, key object is checked for null. If key is null, value is stored in table[0] position. Because hash code for null is always 0.


Step2- Then on next step, a hash value is calculated using key’s hash code by calling its hashCode() method. This hash value is used to calculate index in array for storing Entry object. JDK designers well assumed that there might be some poorly writtenhashCode() functions that can return very high or low hash code value. To solve this issue, they introduced another hash() function, and passed the object’s hash code to this hash() function to bring hash value in range of array index size.


Step3- Now indexFor(hash, table.length) function is called to calculate exact index position for storing the Entry object.


Step4- Here comes the main part. Now, as we know that two unequal objects can have same hash code value, how two different objects will be stored in same array location [called bucket].

Answer is LinkedList. If you remember, Entry class had an attribute “next”. This attribute always points to next object in chain. This is exactly the behavior of LinkedList.

So, in case of collision, Entry objects are stored in LinkedList form. When an Entry object needs to be stored in particular index, HashMap checks whether there is already an entry?? If there is no entry already present, Entry object is stored in this location.

If there is already an object sitting on calculated index, its next attribute is checked. If it is null, and current Entry object becomes next node in LinkedList. If next variable is not null, procedure is followed until next is evaluated as null.

What if we add the another value object with same key as entered before. Logically, it should replace the old value. How it is done? Well, after determining the index position of Entry object, while iterating over LinkedList on calculated index, HashMap calls equals method on key object for each Entry object. All these Entry objects in LinkedList will have similar hash code but equals() method will test for true equality. If key.equals(k) will be true then both keys are treated as same key object. This will cause the replacing of value object inside Entry object only.

In this way, HashMap ensure the uniqueness of keys.
How get() methods works internally
Now we have got the idea, how key-value pairs are stored in HashMap. Next big question is : what happens when an object is passed in get method of HashMap? How the value object is determined?

Answer we already should know that the way key uniqueness is determined in put() method , same logic is applied in get() method also. The moment HashMap identify exact match for the key object passed as argument, it simply returns the value object stored in current Entry object.

If no match is found, get() method returns null.

Let have a look at code:
1.       /** 
2.         * Returns the value to which the specified key is mapped, or {@code null} 
3.         * if this map contains no mapping for the key. 
4.         * 
5.         * <p> 
6.         * More formally, if this map contains a mapping from a key {@code k} to a 
7.         * value {@code v} such that {@code (key==null ? k==null : 
8.         * key.equals(k))}, then this method returns {@code v}; otherwise it returns 
9.         * {@code null}. (There can be at most one such mapping.) 
10.        * 
11.        * </p><p> 
12.        * A return value of {@code null} does not <i>necessarily</i> indicate that 
13.        * the map contains no mapping for the key; it's also possible that the map 
14.        * explicitly maps the key to {@code null}. The {@link #containsKey 
15.        * containsKey} operation may be used to distinguish these two cases. 
16.        * 
17.        * @see #put(Object, Object) 
18.        */  
19.       public V get(Object key) {  
20.        if (key == null)  
21.         return getForNullKey();  
22.        int hash = hash(key.hashCode());  
23.       for (Entry<k , V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {  
24.         Object k;  
25.         if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
26.          return e.value;  
27.        }  
28.        return null;  
29.       }  

Q1. How HashSet implements hashing?
A. Method internally uses HashMap’s hash method for hasihng.
Q2. How add method works internally?
A. public void add(E value){
          hashMapCustom.put(value, null);
}
      Method internally uses HashMap’s put method for storing object.
Q3. How contains method works internally?
A. public boolean contains(E obj){
          return hashMapCustom.contains(obj) !=null ? true :false;
}

     Method internally uses HashMap’s contains method for storing object.

Q4. How remove method works internally?
A. public boolean remove(E obj){
      return hashMapCustom.remove(obj);
 }    
       Method internally uses HashMap’s put remove for storing object.
11) What is jersey weservice, how do you implement it.
12) Have you worked on JMS?
Ans: Yes, refer HCL interview document.
13) Have you used assertion?
14) enumeration example?
15) How @Inject works internally.
7) What was other features introduced in java 5?
Ans:

8) What is architecture of your project?
Ans:

4) Have you worked with Stack and Queue data structure in java?  What is blocking queue, What is Type…

Monday, December 26, 2016

Design Patterns in Java

Design patterns provide architectural solutions to common software design problems. These patterns have emerged over time through the experience and insights of developers. This section introduces some basic patterns that might prove helpful in the context of developing web applications.
You can also find information on these patterns by visiting the following website, which is part of the Java Developer Connection:
The patterns listed below are of particular relevance to the building of web applications. More details are provided in the sections that follow:
  • Front Controller. Coordinates handling of incoming requests. See Front Controllers for more information.
    • Dispatcher. A subpattern of the Front Controller, describing how to control which view the user sees. See Dispatchers for details.
    • View Helper. A subpattern, in this case, to the Front Controller, encapsulating the processing functions, or business rules, such as data access or business logic. See Helpers for more.
  • Composite View. (also called a template) Creates an aggregate view from subcomponents. See Composite Views for additional information.
A full treatment of the use of design patterns in web applications can be found in Core J2EE Patterns by Deepak, Crupi, and Malks. See for more on this book.

Front Controllers

Front Controllers are responsible for routing incoming user requests. In addition, they can enforce navigation in web applications. When users are in sections of a web application where they can browse freely, the Front Controller simply relays the request to the appropriate page. For example, in an e-commerce application, the customer browses through a product catalog. In controlled sections in which users must follow a specific path through the application, the Front Controller can validate the incoming requests and route them accordingly. For example, a customer wants to buy the items in a shopping cart. That customer is required to follow a particular route to complete the purchase successfully.
A Front Controller provides a single entry point through which requests for several resources in a web application pass. One Front Controller might handle all requests to the application. Several Front Controllers might handle requests for portions of the application. Typically implemented as servlets, Front Controllers are frequently used for the following tasks:
  • Controlling page flow and navigation
  • Accessing and managing model data
  • Handling business processing
  • Accessing relevant data to GUI presentation, for example a user profile
Front Controllers can reduce duplication of code in JSP pages, especially in cases where several resources require the same processing. Examples might include ensuring that the user's profile has been found, obtaining the data corresponding to a product ID, and so forth.
You can maintain and control a web application more effectively if you funnel all client requests through a Front Controller. Functions such as view selection, security, and template creation can be centralized in this design pattern. The Front Controller applies these functions consistently across all pages or views. Consequently, when the behavior of these functions needs to change, only the Front Controller and its helper classes need to be changed. They constitute a relatively small portion of the application.
In the two-tier form of a web application, shown in FIGURE 3-1, the recommended approach is for the Front Controller to deal with user requests. The Front Controller also determines which presentation element is to be shown to users and which data is to be used for the chosen presentation. This strategy contrasts to the traditional approach in which each user request must be mapped to a separate view.
Note that Front Controllers do not have to route requests directly to Views. You can chain them so that, for instance, one Front Controller accesses user profile information. Then it could forward that profile to another Front Controller.
 FIGURE 3-1 Determining the User View With a Front Controller
Figure showing contrast between traditional and recommended approaches to determining user views.[ D ]
For information on creating a servlet as a Front Controller using the Forte for Java IDE, see Using the Servlet as a Front Controller.

Dispatchers

Typically, the Front Controller coordinates user navigation, using the Dispatcher subpattern for this purpose. As shown in FIGURE 3-2, the Front Controller processes a request. Perhaps the user might want to check out items in a shopping cart of an e-commerce application.
 FIGURE 3-2 Dispatching as a Function of a Front Controller
Figure showing dispatcher communication with Front Controller to route user requests to appropriate view.[ D ]
Dispatcher code could be contained within the Front Controller servlet, or in a separate class. In practice, the Dispatcher instructs the Front Controller where to forward the request. In the Front Controller design pattern, the Dispatcher encapsulates the behavior that controls which views the user sees.
View Mappers
When web resources differ based on the type of client, you can use a View Mapper to assist the Dispatcher mechanism. Such clients could include a web browser, personal desktop assistant, or cell phone. For instance, you might be developing a web application that retrieves information about waves and tides. In this situation, your users might want to view this data from desktop personal computers or cell phones. Instead of dispatching to a single JSP page, your web application might use the View Mapper to send a different JSP page, depending on the type of client.
1. For example, when your web application receives incoming requests, it routes them to a Front Controller servlet.
2. The Front Controller retrieves the appropriate data using a Helper bean.
3. It then determines the appropriate view type based on the client within the View Mapper.
4. Based on input from the View Mapper, the Dispatcher returns the view information to the Front Controller.
5. The application subsequently forwards the request to the specific view intended for the user's client, as shown in FIGURE 3-3.
 FIGURE 3-3 Using View Mappers
In your wave and tide application, you might not initially know whether you wanted to display the information on a PDA or on a phone. In this case, the View Mapper would enable you to create alternative objects or families of objects.
Use View Mappers not only to redirect information to different devices, but to different locales or different views.

Helpers

The Front Controller servlet can easily become quite large and unwieldy. Therefore, use Helper classes to break out specific features and make the application easier to build and maintain. Here are some tasks that can be encapsulated as Helper classes:
  • Retrieval of content from a file, another website, or even a web service
  • Validation of user-entered information
  • If the Front Controller needs to delegate processing of business logic, it can use Helpers for this purpose, as shown in FIGURE 3-4.
  • Data processing
 FIGURE 3-4 Delegating Processing of Business Logic With Helpers
You can implement Helpers as regular Java classes. See Using Additional Classes or Beans for details.

Composite Views

Composite View is a design pattern that creates an aggregate view from component views. Component views might include dynamic, modular portions of the page. This design pattern pertains to web application design when you are creating a view from numerous subviews. Complex web pages frequently consist of content derived from various resources.The layout of the page is managed independently of the content of its subviews. For instance, a view might have subviews like Navigation, Search, Feature Story, and Headline. An included view is a subview that is one portion of a greater whole. The included view might, in turn, consist of subviews, as shown in FIGURE 3-5.
 FIGURE 3-5 Managing Content Independently From Layout With a Composite View


When creating a Composite View, you can include static content and dynamic content. Static content might consist of an HTML file. Dynamic content might be something like a JSP page. You can also include content at JSP translation time and runtime.
For information on using the Forte for Java IDE to implement a Composite View pattern, see Creating a Composite View Template.

View Creation Helpers

Typically, web pages need to be reused and maintained over time. Use View Creation Helper beans when you need to display data as it is received. Examples of such information might be tables or sets of links. A View Creation Helper can be any bean or Java class. However, since they are specifically geared toward presentation in JSP pages, View Creation Helpers are typically tag handler classes.
The View Creation Helper class provides a way to avoid placing Java code related to specific presentation features directly in the JSP file or Front Controller servlet. For instance, your web application might contain a catalog search that results in certain display results. In this situation, encapsulate the behavior into JSP tags, as shown in FIGURE 3-6:
 FIGURE 3-6 Using View Creation Helpers
Similarly, your web application might require that logic to format data within its views. View Creation Helper beans can be obtained and used in the same manner as any other beans from within a JSP file. See Using Additional Classes or Beans for more information on using the IDE with beans.

Model Objects

Model objects are Java objects that encapsulate application data inside a web application. For instance, in a shopcart e-commerce application, a model object might be an abstraction for a plush toy. Examples of the data would include the toy's name, description, price, stock on hand, and so forth. This information is typically retrieved from database data is inefficient. Hence, you must design session data carefully. For additional information on accessing databases with JDBC, see Using Java DataBase Connectivity, a volume in the Forte for Java Programming Series.
The model object can be passed to the JSP file from a Front Controller servlet two ways:
  • Through a request attribute
  • By placement in the web application's session data
If it makes sense for the application to store product data for a term longer than a single request, then this information can be placed in the application's session.
Typically, all requests from a single user go to a single server where the session information is stored. In a load-balancing system, a single user's requests might be routed to different servers. Hence, session information for a particular user must be shared among servers. This situation can result in slower performance if the web application must synchronize access to the session data.
If the application is to be deployed on a load-balancing system, distributing session data is inefficient. Hence, you must design session data carefully.


Frameworks

Frameworks are sets of design patterns, APIs, and runtime implementations intended to simplify the design and coding process for building new applications. Examples of frameworks are Struts, JATO, and JavaServer Faces, described in the subsequent sections.
Framework designers factor out common functions from existing applications and implement them using appropriate design patterns. A framework enables application developers to concentrate on the unique feature set required by their applications.
Web application frameworks typically provide support for functions such as:
  • Navigating among the application's pages
  • Building forms that accept input from the end user
  • Creating views to display information to the end user
  • Providing access to processing and data with JavaBeans and Enterprise JavaBeans
  • Supplying database access to incorporate information directly from database systems
  • Using directory services such as JNDI (Java Naming and Directory Interface) and LDAP (Lightweight Directory Access Protocol)
  • Providing secure and non-secure access through authentication mechanisms