February 27, 2011

Servlets - Session Management with URL Rewriting

Enable session management through URL rewriting by encoding all the response URLs for the exercise posted at this link - http://www.javaissues.com/2011/02/servlets-session-management-example.html

1) Servlet 1 - Code here: http://www.javaissues.com/2011/02/servlets-handling-get-request.html

2) Servlet 2

package info.icontraining.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class PostServlet extends HttpServlet {
 
   public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

      PrintWriter out = response.getWriter();
       
      String username = request.getParameter("user");
      String passwd = request.getParameter("pass");
      out.println("<html>");
      out.println("<head><title>Post Servlet Example</title></head>"); 
      out.println("<body><h1>");
       
      if (username.equals("dinesh") && passwd.equals("dinesh")) {

         out.println("Welcome " + username +"!<br/><br/>");
         HttpSession session = request.getSession();
         session.setAttribute("username",username);
         out.println("<a href=\"" + response.encodeURL("linkedServlet") + "\">Click here</a>");

      } else {
         out.println("Invalid username/passwd. Go back and try again.");
      }
       
      out.println("</h1></body></html>");
      out.close();
   }
}


3) Servlet 3 - Code here (of Servlet 3): http://www.javaissues.com/2011/02/servlets-session-management-example.html


web.xml configuration for all 3 servlets same as for the example at this link - http://www.javaissues.com/2011/02/servlets-session-management-example.html


To test Session Management with URL rewriting disable cookies in your browser and access the servlets starting with Servlet 1. Observe URL in browser address bar for re-written URL

Servlets - Session Management Example

After user authentication, start a session. Display "Welcome [username]" as the response along with a link that hits another Servlet. From this other servlet, send the response "You are [username]" by retrieving the username information from the session as an attribute.


1) Servlet 1: Code here - http://www.javaissues.com/2011/02/servlets-handling-get-request.html


2) Servlet 2 - PostServlet.java

package info.icontraining.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.*;

public class PostServlet extends HttpServlet {
 
   public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
      PrintWriter out = response.getWriter();
       
      String username = request.getParameter("user");
      String passwd = request.getParameter("pass");
      out.println("<html>");
      out.println("<head><title>Post Servlet Example</title></head>"); 
      out.println("<body><h1>");
       
      if (username.equals("dinesh") && passwd.equals("dinesh")) {

         out.println("Welcome " + username +"!<br/><br/>");
         HttpSession session = request.getSession();
         session.setAttribute("username",username);
         out.println("<a href=\"linkedServlet\">Click here</a>");

      } else {
         out.println("Invalid username/passwd. Go back and try again.");
      }
       
      out.println("</h1></body></html>");
      out.close();
   }
}


3) Servlet 3 - LinkedServlet.java

package info.icontraining.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.*;

public class LinkedServlet extends HttpServlet {
 
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
      PrintWriter out = response.getWriter();
       
      out.println("<html>");
      out.println("<head><title>Session Management Example</title></head>"); 
      out.println("<body><h1>");
             
      HttpSession session = request.getSession();
      String username = (String)session.getAttribute("username");
      out.println("You are " + username +"!");
       
      out.println("</h1></body></html>");
      out.close();
   }
}


web.xml configuration for Servlets 2 & 3 (for configuration of Servlet 1, go to link specified above)

<servlet>
    <servlet-name>postServlet</servlet-name>
    <servlet-class>info.icontraining.servlets.PostServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>postServlet</servlet-name>
    <url-pattern>/formurl</url-pattern>
</servlet-mapping>
 
<servlet>
    <servlet-name>linkedServlet</servlet-name>
    <servlet-class>info.icontraining.servlets.LinkedServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>linkedServlet</servlet-name>
    <url-pattern>/linkedServlet</url-pattern>
</servlet-mapping>

Servlet Initialization Parameters & Context Initialization Parameters

In one of the servlets' configuration, configure a Servlet Initialization parameter and retrieve this parameter value in the servlet code. Configure a Context Initialization parameter and retrieve it in any servlet.

package info.icontraining.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InitParametersDemoServlet extends HttpServlet {
 
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
      PrintWriter out = response.getWriter();
       
      String servletInitParam = getServletConfig().getInitParameter("initParam");
      String contextInitParam = getServletContext().getInitParameter("contextParam");
       
      out.println("<html><body>");
       
      out.println("<p>Servlet Init Parameter Value = ");
      out.println(servletInitParam + "<br/><br/>");
       
      out.println("Context Init Parameter Value = ");
      out.println(contextInitParam + "<br/><br/>");
       
      out.println("</p></body></html>");
      out.close();
   }
}


Configuration for the servlet (along with Servlet Initialization Parameter) and the Context Initialization parameter,

<servlet>
   <servlet-name>initParametersDemoServlet</servlet-name>
   <servlet-class>info.icontraining.servlets.InitParametersDemoServlet</servlet-class>
   <init-param>
      <param-name>initParam</param-name>
      <param-value>initValue</param-value>
   </init-param>
</servlet>
<servlet-mapping>
   <servlet-name>initParametersDemoServlet</servlet-name>
   <url-pattern>/initParameters</url-pattern>
</servlet-mapping>
 
<context-param>
   <param-name>contextParam</param-name>
   <param-value>contextValue</param-value>
</context-param>


URL in browser:

http://localhost:8080/WebAppName/initParameters

February 26, 2011

Servlets - Overriding init & destroy methods

Override the init() and destroy() methods of a Java Servlet program

package info.icontraining.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InitDemoServlet extends HttpServlet {
 
   public void init() {
      System.out.println("Inside init method");
   }
 
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
      System.out.println("Inside doGet");
   }
 
   public void destroy() {
      System.out.println("Inside destroy method");
   }
}


Adding Servlet configuration in the web.xml

<servlet>
    <servlet-name>initDemoServlet</servlet-name>
    <servlet-class>info.icontraining.servlets.InitDemoServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>initDemoServlet</servlet-name>
    <url-pattern>/initDemo</url-pattern>
</servlet-mapping>


How to test:

1) Open URL: http://localhost:8080/WebAppName/initDemo

2) Check Server console log, it should show "Inside Init method" and "Inside doGet".

3) Refresh browser screen, now server console should show only "Inside doGet". Refresh several more times.

4) Stop the server, search through the server log for "Inside destroy method".

Servlets - Handling a POST request

Write a servlet to handle a POST request. This request should procure the form data on the server side and send an HTML response that prints "Welcome [username]" or "Incorrect username/password" based on whether login was successful or a failure.

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.http.*;

public class PostServlet extends HttpServlet {
 
   public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
      PrintWriter out = response.getWriter();
       
      String username = request.getParameter("user");
      String passwd = request.getParameter("pass");
      out.println("<html>");
      out.println("<head><title>Post Servlet Example</title></head>"); 
      out.println("<body><h1>");
       
      if (username.equals("dinesh") && passwd.equals("dinesh")) {
         out.println("Welcome " + username);
      } else {
         out.println("Incorrect username/password.");
      }
       
      out.println("</h1></body></html>");
      out.close();
   }
}

Add the following configuration to the web.xml,

<servlet>
   <servlet-name>postServlet</servlet-name>
   <servlet-class>info.icontraining.servlets.PostServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>postServlet</servlet-name>
   <url-pattern>/formurl</url-pattern>
</servlet-mapping>


The servlet can be accessed through the GET Servlet at this URL

Servlets - Handling a GET request

Write a servlet to handle a GET request. This request should send a response that is an HTML form for logging in.

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.http.*;

public class GetServlet extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response)   throws IOException {

      PrintWriter out = response.getWriter();
      out.println("<html>");
      out.println("<body>");
      out.println("<h2>Get Servlet Example</h2>");
      out.println("<form action=\"formurl\" method=\"post\">");
      out.println("Login<br/> ");
      out.println("<input type=\"text\" name=\"user\" /><br/>");
      out.println("Password<br/> ");
      out.println("<input type=\"password\" name=\"pass\" /><br/>");
      out.println("<input type=\"submit\" value=\"Login\" />");
      out.println("</form>");
      out.println("</body></html>");
      out.close();
  }
}


Add the following configuration in the web.xml,

<servlet>
   <servlet-name>getServlet</servlet-name>
   <servlet-class>info.icontraining.servlets.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>getServlet</servlet-name>
   <url-pattern>/login</url-pattern>
</servlet-mapping>


Access the servlet by typing the following URL in the browser,

http://localhost:8080/WebAppName/login

February 19, 2011

Servlets - Hello World Example

Create a HelloServlet.java source file in the src folder,

HelloServlet.java

package info.icontraining.servlets;

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;

public class HelloServlet extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
      PrintWriter out = response.getWriter();
      out.println("Hello World");
      out.close();
   }
}

In the WebContent/WEB-INF/web.xml configuration file, add the following configuration,

web.xml

<servlet>
   <servlet-name>helloServlet</servlet-name>
   <servlet-class>info.icontraining.servlets.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>helloServlet</servlet-name>
   <url-pattern>/hello</url-pattern>
</servlet-mapping>


Now access the servlet from a browser, typing the following URL,

http://localhost:8080/WebAppName/hello

February 9, 2011

javax.faces.FacesException: Cant set managed bean property:



Topic: JSF 1.2

Application Server: JBoss 4.2.2GA

Exception:

javax.faces.FacesException: Cant set managed bean property: personname.
at com.sun.faces.application.ApplicationAssociate.createAndMaybeStoreManagedBeans(ApplicationAssociate.java:556)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:82)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:45)
at org.apache.el.parser.AstValue.getValue(AstValue.java:86)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
at javax.faces.component.UIOutput.getValue(UIOutput.java:173)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:189)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:320)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:200)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:836)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:896)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:137)


java.lang.NoSuchMethodException: Unknown property 'personname'
at com.sun.org.apache.commons.beanutils.PropertyUtils.setSimpleProperty(PropertyUtils.java:1777)
at com.sun.faces.config.ManagedBeanFactoryImpl.setPropertiesIntoBean(ManagedBeanFactoryImpl.java:647)
at com.sun.faces.config.ManagedBeanFactoryImpl.newInstance(ManagedBeanFactoryImpl.java:317)
at com.sun.faces.application.ApplicationAssociate.createAndMaybeStoreManagedBeans(ApplicationAssociate.java:546)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:82)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)


Resolution:

The managed property name set in the faces-config.xml file within the <managed-property> and the <property-name> elements does not match with the JavaBean property name as in the Managed Bean class and/or with the property name in the JSF tags in the JSPs. The property name in the managed bean class, as per JavaBean conventions, must be the same as set in the faces-config.xml configuration file as well as the property name used in the JSF tags in any of the JSPs.

Exception sending context initialized event to listener instance of class org.jboss.web.jsf.integration.config.JBossJSFConfigureListener javax.faces.FacesException: Can't parse configuration file: jndi:/localhost/AppName/WEB-INF/faces-config.xml


Topic: JSF 1.2

Application Server: JBoss 4.2.2GA

Exception:

Exception sending context initialized event to listener instance of class org.jboss.web.jsf.integration.config.JBossJSFConfigureListener
javax.faces.FacesException: Can't parse configuration file: jndi:/localhost/JSFWebapp/WEB-INF/faces-config.xml: Error at line 17 column 5: The element type "managed-bean-scope" must be terminated by the matching end-tag "</managed-bean-scope>".
at com.sun.faces.config.ConfigureListener.parse(ConfigureListener.java:1438)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:376)
at org.jboss.web.jsf.integration.config.JBossJSFConfigureListener.contextInitialized(JBossJSFConfigureListener.java:69)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3856)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4361)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:790)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:770)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:553)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)


Resolution:

The exception occurs due to an error in the JSF-specific configuration file, faces-config.xml, which must comply with XML rules for well-formed-ness and validity. Check for an incorrectly terminated XML element or an incorrectly spelled element, or other such errors in the faces-config.xml

The error message in the Server console log also pin-points the line number where the error has occured, fairly well.

Exception sending context initialized event to listener instance of class org.jboss.web.jsf.integration.config.JBossJSFConfigureListener javax.faces.FacesException: java.lang.ClassCastException: com.sun.faces.lifecycle.LifecycleFactoryImpl

Topic: JSF 1.2

Application Server: JBoss 4.2.2GA

Exception:


ERROR [[/JSFWebapp]] Exception sending context initialized event to listener instance of class org.jboss.web.jsf.integration.config.JBossJSFConfigureListener
javax.faces.FacesException: java.lang.ClassCastException: com.sun.faces.lifecycle.LifecycleFactoryImpl
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:387)
at org.jboss.web.jsf.integration.config.JBossJSFConfigureListener.contextInitialized(JBossJSFConfigureListener.java:69)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3856)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4361)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:790)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:770)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:553)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:296)
at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.apache.catalina.core.StandardContext.init(StandardContext.java:5312)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)



Resolution:


Removing 2 jars: jsf-api.jar and jsf-impl.jar removed the exception for me. However, some other jars that may have to be removed: el-api.jar, el-ri.jar, jsf-tlds.jar

The exception is caused, apparently, due to a versioning issue between the jars in the lib of the Web Application and the jars in the JBoss Application Server.

February 8, 2011

Java Server Faces (JSF) - Hello World Example Code

Jars to be added to the lib folder of the Web Application


commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-logging.jar
jstl.jar
standard.jar
jsf-api.jar
jsf-impl.jar


Java Threads Synchronization

Create a class MyJob that implements the Runnable interface with an instance variable myString of type String - in the run() method of MyJob, add the following code

myString = ""; // this lines goes in the constructor of the MyJob class

for(int i=0; i<10; i++) {
   myString = myString + i;
   System.out.println("myString being formed by thread: " + Thread.currentThread().getName());
}
System.out.println(myString);

In the main() method of another class Test, spawn 2 threads:

MyJob mj = new MyJob();
Thread t1 = new Thread(mj);
Thread t2 = new Thread(mj);
t1.setName("FirstThread");
t2.setName("SecondThread");
t1.start();
t2.start();

What is the output?

What change would you do to make myString assign an ordered String such as 01234567890123456789?

Solution


MyJob.java

public class MyJob implements Runnable {

   private String MyString;
 
   public MyJob() {
      MyString = "";
   }

   public synchronized void run() {

      for(int i=0; i<10; i++) {
         MyString = MyString + i;
         System.out.println("MyString being formed by thread: "
                     + Thread.currentThread().getName());
      }
      System.out.println(MyString);
   }
}

Test.java

public class Test {

   public static void main(String[] args) {

      MyJob mj = new MyJob();

      Thread t1 = new Thread(mj);
      Thread t2 = new Thread(mj);

      t1.setName("FirstThread");
      t2.setName("SecondThread");

      t1.start();
      t2.start();
   }
}

Java Threads Basic Example

Creating a new thread of execution by extending the Thread class

public class MyThread extends Thread {

   public void run() {
      for(int i=0; i<20; i++) {
         System.out.println("In thread: " + Thread.currentThread().getName());
      }
   }
}

public class Driver {

   public static void main(String[] args) {

      MyThread t = new MyThread();
      t.setName("MyThread");
      t.start();

      for(int i=0; i<20; i++) {
         System.out.println("In thread: " + Thread.currentThread().getName());
      }
   }
}

Creating a new thread of execution by implementing the Runnable interface

public class MyRunnable implements Runnable {

   public void run() {
      for(int i=0; i<20; i++) {
         System.out.println("In thread: " + Thread.currentThread().getName());
      }
   }
}

public class Driver {

   public static void main(String[] args) {

      MyRunnable r = new MyRunnable();
      Thread t = new Thread(r);
      t.setName("MyRunnable");
      t.start();

      for(int i=0; i<20; i++) {
         System.out.println("In thread: " + Thread.currentThread().getName());
      }
   }
}

The second method (implementing Runnable) is preferred over the first method (extending Thread)

February 5, 2011

Inner Classes in Java

Inner classes are classes defined within another class as a member of that class. The inner class code has access to members of the enclosing outer class, including those members marked private.


public class Outer {

   private int i;

   public void makeInner {
      Inner inner = new Inner();
      inner.accessOuter;
   }

   class Inner {
      public void accessOuter {
         i = 7;
         System.out.println("Outer class, i=" + i);
      }
   }

   public static void main(String[] args) {
      Outer outer = new Outer();
      outer.makeInner();

      Outer.Inner inner = new Outer().new Inner();
      inner.accessOuter();
   }
}

Exception Handling in Java

Java's Exception-handling mechanism cleanly separates the exception-generating code from the exception-handling code.


import java.io.*;
import java.sql.*;

public class Test {

   public void m1() throws ClassNotFoundException {

      try {
  
         FileReader f = new FileReader("test.txt");
                   // throws FileNotFoundException

         Connection c = DriverManager.getConnection("test");
                   // throws SQLException

         Class.forName(info.icontraining.Test);
                   // throws ClassNotFoundException

      } catch (FileNotFoundException e) {
         System.err.println(e.getMessage());
      } catch (SQLException e) {
         System.err.println(e.getMessage()); 
      } catch (Exception e) {
         System.err.println("catch all other exceptions");
         System.err.println(e.getMessage());
      } finally {
         System.out.println("In the finally block");
      }
   }

   public static void main(String[] args) {

      Test t = new Test();
      
      try {
         t.m1();
      } catch (ClassNotFoundException e) {
         System.err.println(e.getMessage());
      }
   }
}

Garbage collection in Java: Islands of Isolation

"Islands of Isolation" refers to objects with circular references to each other but with no reference to any of the objects from a Java program.

The following program creates an Island of Isolation of 3 objects.

public class Test {
   private Test next;

   public static void main(String[] args) {

      Test t1 = new Test();
      Test t2 = new Test();
      Test t3 = new Test();

      t1.next = t2;
      t2.next = t3;
      t3.next = t1;

      t1 = null;
   } 
}

finalize method in Java

The finalize() method can be overridden in any Java class (from the Object class), and will be invoked and executed by the JVM just before the object is deleted by the Garbage collector.

public class Test {

   public void finalize() {
      System.out.println("In finalize method");
   }

   public static void main(String[] args) {
      Test t = new Test();
      t = null;
   }
}

Arrays in Java

Arrays in Java are represented as objects. When an array is constructed all its elements are initialized with defaults values (irrespective of whether the array is declared as an instance variable or local variable).

Constructing an array of object references constructs only the array objects and not the objects themselves.

public class Test {

   private static int[] intArr = new int[3];

   public static void main(String[] args) {

      Test[] testArr = new Test[2];

      for (int i=0; i < testArr.length; i++) {
         System.out.println(testArr[i]);
      }

      for (int j=0; j < intArr.length; j++) {
         System.out.println(intArr[j]);
      }

      intArr[0] = 3;
      testArr[1] = new Test();
   }
}

February 3, 2011

How Constructors work in Java

Create a Class A with a no-arg constructor - print "In A constructor"
Create Class B as a subclass of A - put a constructor with one argument to this constructor - print "In B constructor".
Create Class C as a subclass of B.
In the main method create an object of Class C as follows,
C c = new C(); // Make this line work!

Solution


A.java

public class A {
   public A() {
      System.out.println("In A constructor");
   }        
}

B.java

public class B extends A {
   public B(int i) {
      System.out.println("In B constructor");
   }  
}

C.java


public class C extends B {
   public C() {
      super(3);       
      System.out.println("In C constructor");
   }        
}

Driver.java

public class Driver {
   public static void main(String[] args) {
      C c = new C();
   }
}

February 2, 2011

Scope of Variables in Java

Static variables have the longest scope - they are created when the class is loaded by the JVM Classloader and survive as long as the class stays loaded.
Instance variables are created when a new instance of the class is created and live until the instance is removed.

Local variables are created when execution enters the method and live as long as the method remains on the stack (or the method completes execution).
Block variables live only as long as the code block is executing.


public class Test {
   private int i;          // instance variable
   private static int j;   // static variable

   public void m1() {
      int k=0;       // local variable

      if (true) {
         int m=0;    // block variable
      }
   }
}

Access issues from a static context in Java

A static method (context) cannot directly access instance members (variable and method) of a class. It can only access the static members directly.



public class Test {
   private int i;
   private static int j;
   
   public void m1() {
      System.out.println("Inside method m1");
   }

   public static void m2() {
      System.out.println("Inside method m2");
   }

   public static void m3() {
      j = 3;
      m2();         // can access static members

      Test t = new Test();
      t.i = 4;      // can access instance members
      t.m1();       // indirectly (on a reference)


      i = 3;        // cannot access instance members
      m1();         // directly - will not compile
   } 
}

Method Overriding and Overloading together in Java

A Java method can overridden and overloaded at the same time.


public class SuperClass {
   public void m1() {
      System.out.println("In SuperClass");
   }
}

public class SubClass extends SuperClass {
   public void m1() {
      System.out.println("In SubClass");
   }

   public void m1(int i) {
      System.out.println("Overloaded method in SubClass");
   }
}

super keyword in Java

The super keyword can be used to invoke an overridden method in the superclass from the overriding method in the subclass

public class SuperClass {
   public void m1() {
      System.out.println("In SuperClass");
   }
}

public class SubClass extends SuperClass {
   public void m1() {
      super.m1();
      System.out.println("In SubClass");
   }
}

It can also be used to invoke a superclass constructor from the subclass constructor.


public class SuperClass {
   public SuperClass() {
      System.out.println("In SuperClass constructor");
   }
}

public class SubClass extends SuperClass {
   public SubClass() {
      super();
      System.out.println("In SubClass Constructor");
   }
}

February 1, 2011

Effect of abstract keyword on classes and methods

A class marked with the abstract keyword cannot be instantiated. It has to be subclassed to be useful.

public abstract class Test {
   public static void main(String[] args) {
      Test t = new Test();       // will not compile    
   }
}

A method marked as abstract cannot have a body (is not implemented) and ends with a semi-colon.

public abstract class Test {
   public abstract void m1();
}

Abstract classes may have abstract methods.
But an abstract method must be present in an abstract class.
Non-abstract (Concrete) classes cannot have abstract methods.

public class Test {
   public abstract void m1(); // will not compile
}

public abstract class Test {
   public abstract void m2() {  // will not compile

   }
}

Effect of final keyword on variables, methods & classes in Java

Effect on final on variables
A primitive variable marked final cannot be reassigned once it has been initialized with an explicit value
A reference variable marked final cannot be reassigned to refer to a different object, though the state of the object can be changed.

public class Test {
  
   String s;  

   public static void main(String args[]) {
      final int i;
      i = 3;
      i = 4;              // will not compile

      final Test t;
      t = new Test();
      t.s = "Hello";
      t.s = "World";

      t = new Test();     // will not compile

   }
}

Effect on final on methods
Methods marked as final cannot be overridden in the subclass.

public class Test {
   public final void m1() {
      System.out.println("Superclass");
   }
}

public class A extends Test {
   public void m1() {                 // will not compile
      System.out.println("Subclass");
   }
}

Effect on final on classes
Classes marked as final cannot be subclassed.

public final class Test {

}

public class A extends Test {       // will not compile

}

Difference between Instance, Local, Reference, Primitive Variables in Java

public class Test {
   // instance variable of primitive type
   private int i;

   // instance variable of Reference type
   private String s;      

   public void m1() {
      // local variable of primitive type
      int j = 3;

      // local variable of Reference type
      String t = "Hello";  
   }
}

Access Modifiers for a Java Class

public is the only access modifier that can be applied on a Java class.
Classes with public access can be accessed by other classes in all packages. Classes with default access level (no public access modifier applied) can be accessed by other classes within the same package only.

package info.icontraining.p1;
import info.icontraining.p2.A;
public class Test {
    public void m1() {
         A a = new A();
         // B b = new B();  // un-commenting causes a compile error
    }
}

package info.icontraining.p2;
import info.icontraining.p1.Test;
public class A {
    public void m1() {
         Test t = new Test();
    }
}

package info.icontraining.p2;
import info.icontraining.p1.Test;
class B {

    public void m1() {
         Test t = new Test();
    }
}

Classes A and B (present in the same package ) can access class Test (present in a different package).
Class Test can access A (since it is public), but cannot access B (since it is default).