Java Puzzlers on local variable initialization

Intent of my blog

Some time back, i posted a blog on common interview questions on overriding.The blog was very popular on dzone so i decided to write some of the java puzzlers on local variable initialization.One thing which should be kept in mind is that Local variables should be initalized before they are used.Knowing this fact try to answer these questions.

Local Variable Initialization Puzzlers

Question1


public class Question1{
 public static void main(String[] args) {
 int x;
 int y = 10;
 if (y == 10) {
 x = y;
 }
 System.out.println("x is " + x);
 }
}

Question 2


class Question2{
 public static void main(String[] args) {
 int x;
 if(true){
 x = 10;
 }
 System.out.println("x is " + x);
 }
}

Question 3


class Question3{
 public static void main(String[] args) {
 int x;
 final int y = 10;
 if(y == 10){
 x = 10;
 }
 System.out.println("x is " + x);

 }
}

Question 4


class Question4{
 static int y = 10;

 public static void main(String[] args) {
 int x ;
 if(y == 10){
 x = 10;
 }
 System.out.println("x is " + x);
 }
}

Question 5


class Question5{
 static final int y = 10;

 public static void main(String[] args) {
 int x ;
 if(y == 10){
 x = 10;
 }
 System.out.println("x is " + x);
 }
}

Again, like the previous post, i am not posting the solutions because i dont want to take away the fun. So, play with these and have fun.

Overriding Question asked in interviews

Intent of my Blog

Overriding is the concept which is very much asked in the interview.In almost every interview i have given or taken overriding questions were present.So, i decided to document all the possible overriding questions.Try out these questions and have fun.

What is Overriding?

According to wikipedia

“Method overriding, in object oriented programming, is a language feature that allows a subclass to provide a specific implementation of a method that is already provided by one of its superclasses. The implementation in the subclass overrides (replaces) the implementation in the superclass.”

Overriding Questions

Question 1

public class OverridingQuestion1 {

 public static void main(String[] args) {
 A a = new A();
 a.execute();
 B b = new B();
 b.execute();
 a = new B();
 a.execute();
 b = (B) new A();
 b.execute();
 }

}

class A {
 public void execute() {
 System.out.println("A");
 }
}

class B extends A {
 @Override
 public void execute() {
 System.out.println("B");
 }
}

Question 2


class A1 {

 private void prepare(){
 System.out.println("Preparing A");
 }
}

class B1 extends A1 {

 public void prepare(){
 System.out.println("Preparing B");
 }
 public static void main(String[] args) {
 A1 a1 = new B1();
 a1.prepare();
 }
}

Question 3

public class OverridingQuestion3 {

 public static void main(String[] args) {
 A2 a2 = new A2();
 System.out.println(a2.i);
 B2 b2 = new B2();
 System.out.println(b2.i);
 a2 = new B2();
 System.out.println(a2.i);
 }

}
class A2{
 int i = 10;

}
class B2 extends A2{
 int i = 20;

}

Question 4


public class OverridingQuestion4 {

 public static void main(String[] args) {
 A3 a3 = new A3();
 a3.execute();
 B3 b3 = new B3();
 b3.execute();
 a3 = new B3();
 a3.execute();
 b3 = (B3)new A3();
 b3.execute();
 }

}

class A3{
 public static void execute(){
 System.out.println("A3");
 }

}
class B3 extends A3{
 public static void execute(){
 System.out.println("B3");
 }
}

Question 5


public class OverridingQuestion5 {

 public static void main(String[] args) {
 A4 a4 = new B4();
 a4.execute();
 }

}

class A4{
 public void execute() throws Exception{
 System.out.println("A");
 }
}
class B4 extends A4{
 @Override
 public void execute(){
 System.out.println("B");
 }
}

As if now i can think of the above 5 questions. If you have any other overriding question, please put that in comment.
I am not posting solution to these questions. So, try these, and post the solution in comments.

Again fallen into java puzzler trap– Another Java Puzzler

Intent of My Blog
Today, while writing a piece of code, i found that i have again fallen into a java trap.This is a java puzzler that i read in java puzzler book.

What is the output of this java puzzler?

public class JavaPuzzler {

public static void main(String[] args) {
JavaPuzzler javaPuzzler = null;
System.out.println(javaPuzzler.get());
}

private static String get(){
return "i am a java puzzler";
}

}

Before reading the answer ,please try running this in eclipse and see whether you got it correct.

Solution

You might think that it should throw NullPointerException because the main method invokes get() method  on local variable which is initialized to null, and you can’t invoke a method on null.

But if you run this program, you will see that it prints “i am a java puzzler” . The reason  is that get() is a static method.

File Upload on Google App Engine using struts2

Intent of my Blog

Few months back, i wrote a blog on Creating Struts2 application on Google App Engine and some developers asked me how to upload a file using struts2 on google app engine. At that point of time, i was playing with google app engine and was not very clear about the limitation google app engine imposes. Google App Engine does not allow your application to write a file to their application server. This was a very big limitation as most of the application require some sort of file upload. So, i decided to find some way by which i can achieve the upload functionality and i found this link. But, i didn’t wanted to use servelt in my code because i was trying to build a application using struts 2.I wanted to work with actions and use FileUploadInterceptor. With the current implementation of struts 2 FileUploadInterceptor, i can’t do fileupload because it writes file to server.So, after spending some time with struts2 code, i wrote my own extension for Struts 2.This post will discuss how you can use small struts2 wrapper framework, i created for google app engine in your application to do fileupload and more.

Prerequisites for starting Struts2 Application on Google App Engine

Before you start building your sample application on google app engine using struts 2 you will need the following:-

  1. Google App Engine runs on java 5 and above so if necessary, download and install the Java SE Development Kit (JDK) for your platform and for mac users download and install the latest version.
  2. In this example we will be using Eclipse as our ide. So if necessary, download eclipse and google app engine plugin for eclipse.You will also need to download the google  java app engine SDK. For more information you can refer to installing the java SDK for google app engine.
  3. Download the latest release of Struts2 framework.If you want to learn struts 2 a very good reference is struts 2 in action book.Please buy Struts 2 in Action.
  4. Download the latest release of struts2-gae framework.It is an wrapper around struts 2 for google app engine.

Step by Step procedure to create Struts2 File Upload application on Google App Engine.

Step 1: Create a new project by clicking the New Web Application Project button in the toolbarnew_app_button.

1

Step 2 : Give the project name say struts2-fileupload  as we are going to create a simple file upload application. Enter package name as com.login and uncheck “Use Google Web Toolkit,” and ensure “Use Google App Engine” is checked and click the finish button.

s1

Step3 : When you click the finish button you will get a sample HelloWorld application, which you can run going in the Run menu, select Run As > Web Application.By default application will run at port 8080, you can view the sample application at http://locahost:8080. For more information on the sample google web application created by the plugin you can refer to Google java app engine documentation .Please keep in mind that intent of this document is not to provide developers the overview of Google App engine for Java.

Step4 : By now you are ready with the google app engine infrastructure and we can move to the next step of creating a file upload application in Struts 2.

  • for creating a struts 2 application you will need to first add the required dependencies to the struts2-fileupload project. The required struts 2 jars are below mentioned and you can find these jars in struts2 package you downloaded inside the lib folder :-
    • commons-fileupload-1.2.1.jar
    • commons-io-1.3.2.jar
    • commons-logging-1.1.jar
    • freemarker-2.3.13.jar
    • ognl-2.6.11.jar
    • struts2-core-2.1.6.jar
    • struts2-gae-0.1.jar
    • xwork-2.1.2.jar
  • Add these dependencies in your eclipse java build path.

s2

  • Add these dependencies in the war/WEB-INF/lib folder so that these jars gets deployed along with your application.
  • First step in creating a struts 2 application is configuring the web.xml (deployment descriptor) which is located in WEB-INF folder.You can remove the servlet declaration from web.xml as we will not be needing this.In the last post,we configured FilterDispatcher(this is theFilterDispatcher which comes with struts2) but in this application we need to add the GaeFilterDispatcher(this is provided by struts 2 extension framework for GAE). We will declare GaeFilterDispatcher in web.xml, because in struts2 every request goes  pass through a FilterDispatcher, which will invoke the appropriate action corresponding to the URL mapping.So our web.xml will look like :-
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
 <filter>
 <filter-name>struts2-gae</filter-name>
 <filter-class>com.struts2.gae.dispatcher.GaeFilterDispatcher</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>struts2-gae</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
 <welcome-file-list>
 <welcome-file>index.html</welcome-file>
 </welcome-file-list>
</web-app>
  • To start we will be creating a jsp fileupload page using struts 2 tag library and we will call file upload page from index.html.To call the fileupload page there are two ways first, we can directly call the upload.jsp page from link second, we can calling it through struts. We will be taking the second step as this will show you how to configure actions when you dont need to invoke any action.Lets first see how our login page and index.html will look like :-

index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Struts2 File upload on Google App Engine</title>
</head>

<body>
<h1>Struts2 File upload on Google App Engine!</h1>
<table>
<tr>
<td colspan="2" style="font-weight: bold;">Available Application:</td>
</tr>
<tr>
<td><a href="/add" />Upload my Photo</td>
</tr>
</table>
</body>
</html>

upload.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"</pre>
 pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload my Photo</title>
</head>
<body>
 <s:form action="upload" method="post" enctype="multipart/form-data">
 <s:file name="photo" label="Upload new Photo"></s:file>
 <s:submit value="Upload"></s:submit>
 </s:form>

</body>
</html>

After creating the upload.jsp we need to configure this as action in the struts.xml file which you be should put inside source folder parallel to log4j.properties file.We can configure action as mentioned below:-

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<include file="struts-default.xml"></include>
<package name="" namespace="/" extends="struts-default">
		<action name="add">
			<result>/upload.jsp</result>
		</action>
	</package>
</struts>
  • Now try running this application by right click on project run as > web application and click http://localhost:8080. You will see index.html and when you click on upload my photo you will get this exception :-

SEVERE: Unable to set parameter [location] in result of type    [org.apache.struts2.dispatcher.ServletDispatcherResult]

Caught OgnlException while setting property ‘location’ on type ‘org.apache.struts2.dispatcher.ServletDispatcherResult’. – Class: ognl.OgnlRuntime

File: OgnlRuntime.java

Method: invokeMethod

Line: 508 – ognl/OgnlRuntime.java:508:-1

at com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:392)

Caused by: java.lang.IllegalAccessException: Method [public void org.apache.struts2.dispatcher.StrutsResultSupport.setLocation(java.lang.String)] cannot be accessed.

at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:508)

at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:812)

at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:964)

at ognl.ObjectPropertyAccessor.setPossibleProperty(ObjectPropertyAccessor.java:75)

at ognl.ObjectPropertyAccessor.setProperty(ObjectPropertyAccessor.java:131)

at com.opensymphony.xwork2.ognl.accessor.ObjectAccessor.setProperty(ObjectAccessor.java:28)

at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:1656)

at ognl.ASTProperty.setValueBody(ASTProperty.java:101)

at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:177)

at ognl.SimpleNode.setValue(SimpleNode.java:246)

at ognl.Ognl.setValue(Ognl.java:476)

at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:192)

at com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:385)

… 73 more

  • In order to resolve this problem we  need to make entry in web.xml file also for OgnlListener.This OgnlListener is also provided by struts2-gae framework.(A struts2 extension framework for GAE).

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns="http://java.sun.com/xml/ns/javaee&quot;
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot; version="2.5">
<filter>
<filter-name>struts2-gae</filter-name>
<filter-class>com.struts2.gae.dispatcher.GaeFilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2-gae</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.struts2.gae.listener.OgnlListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

  • You need to add this step if you are using Google App Engine 1.2.6 because when you run struts2 application on google app engine 1.2.6 you will get the following error:-

javax.servlet.ServletException: java.lang.NoClassDefFoundError: javax.swing.tree.TreeNode is a restricted class. Please see the Google App Engine developer’s guide for more details.
at org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:825)
at org.apache.jasper.runtime.PageContextImpl.access$1100(PageContextImpl.java:64)
at org.apache.jasper.runtime.PageContextImpl$12.run(PageContextImpl.java:745)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:743)
at org.apache.jsp.login_jsp._jspService(login_jsp.java:86)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
at com.google.appengine.tools.development.PrivilegedJspServlet.access$101(PrivilegedJspServlet.java:23)
at com.google.appengine.tools.development.PrivilegedJspServlet$2.run(PrivilegedJspServlet.java:59)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.appengine.tools.development.PrivilegedJspServlet.service(PrivilegedJspServlet.java)

To avoid this error you need to create a new package “freemarker.core” in your source folder and add the following class

</span></span>

/*
 * Copyright (c) 2003 The Visigoth Software Society. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above
copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowledgement:
 *       "This product includes software developed by the
 *        Visigoth Software Society (http://www.visigoths.org/)."
 *    Alternately, this acknowledgement may appear in the software
itself,
 *    if and wherever such third-party acknowledgements normally
appear.
 *
 * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names
of the
 *    project contributors may be used to endorse or promote products
derived
 *    from this software without prior written permission. For written
 *    permission, please contact visigo...@visigoths.org.
 *
 * 5. Products derived from this software may not be called
"FreeMarker" or "Visigoth"
 *    nor may "FreeMarker" or "Visigoth" appear in their names
 *    without prior written permission of the Visigoth Software
Society.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Visigoth Software Society. For more
 * information on the Visigoth Software Society, please see
 * http://www.visigoths.org/
 */

package freemarker.core;

import java.io.IOException;

/**
 * A TemplateElement representing a block of plain text.
 *
 * @version $Id: TextBlock.java,v 1.17 2004/01/06 17:06:42 szegedia Exp $
 */
public final class TextBlock extends TemplateElement {
 private static final char[] EMPTY_CHAR_ARRAY = new char[0];
 static final TextBlock EMPTY_BLOCK = new TextBlock(EMPTY_CHAR_ARRAY, false);
 // We're using char[] instead of String for storing the text block because
 // Writer.write(String) involves copying the String contents to a char[]
 // using String.getChars(), and then calling Writer.write(char[]).By
 // using Writer.write(char[]) directly, we avoid array copying on each
 // write.
 private char[] text;
 private final boolean unparsed;

 public TextBlock(String text) {
 this(text, false);
 }

 public TextBlock(String text, boolean unparsed) {
 this(text.toCharArray(), unparsed);
 }

 private TextBlock(char[] text, boolean unparsed) {
 this.text = text;
 this.unparsed = unparsed;
 }

 /**
 * Simply outputs the text.
 */
 public void accept(Environment env) throws IOException {
 env.getOut().write(text);
 }

 public String getCanonicalForm() {
 String text = new String(this.text);
 if (unparsed) {
 return "<#noparse>" + text + "</#noparse>";
 }
 return text;
 }

 public String getDescription() {
 String s = new String(text).trim();
 if (s.length() == 0) {
 return "whitespace";
 }
 if (s.length() > 20) {
 s = s.substring(0, 20) + "...";
 s = s.replace('\n', ' ');
 s = s.replace('\r', ' ');
 }
 return "text block (" + s + ")";
 }

 TemplateElement postParseCleanup(boolean stripWhitespace) {
 if (text.length == 0)
 return this;
 int openingCharsToStrip = 0, trailingCharsToStrip = 0;
 boolean deliberateLeftTrim = deliberateLeftTrim();
 boolean deliberateRightTrim = deliberateRightTrim();
 if (!stripWhitespace || text.length == 0) {
 return this;
 }
 if (parent.parent == null && previousSibling() == null)
 return this;
 if (!deliberateLeftTrim) {
 trailingCharsToStrip = trailingCharsToStrip();
 }
 if (!deliberateRightTrim) {
 openingCharsToStrip = openingCharsToStrip();
 }
 if (openingCharsToStrip == 0 && trailingCharsToStrip == 0) {
 return this;
 }
 this.text = substring(text, openingCharsToStrip, text.length
 - trailingCharsToStrip);
 if (openingCharsToStrip > 0) {
 this.beginLine++;
 this.beginColumn = 1;
 }
 if (trailingCharsToStrip > 0) {
 this.endColumn = 0;
 }
 return this;
 }

 /**
 * Scans forward the nodes on the same line to see whether there is a
 * deliberate left trim in effect. Returns true if the left trim was
 * present.
 */
 private boolean deliberateLeftTrim() {
 boolean result = false;
 for (TemplateElement elem = this.nextTerminalNode(); elem != null
 && elem.beginLine == this.endLine; elem = elem
 .nextTerminalNode()) {
 if (elem instanceof TrimInstruction) {
 TrimInstruction ti = (TrimInstruction) elem;
 if (!ti.left && !ti.right) {
 result = true;
 }
 if (ti.left) {
 result = true;
 int lastNewLineIndex = lastNewLineIndex();
 if (lastNewLineIndex >= 0 || beginColumn == 1) {
 char[] firstPart = substring(text, 0,
 lastNewLineIndex + 1);
 char[] lastLine = substring(text, 1 + lastNewLineIndex);
 if (trim(lastLine).length == 0) {
 this.text = firstPart;
 this.endColumn = 0;
 } else {
 int i = 0;
 while (Character.isWhitespace(lastLine[i])) {
 i++;
 }
 char[] printablePart = substring(lastLine, i);
 this.text = concat(firstPart, printablePart);
 }
 }
 }
 }
 }
 if (result) {
 }
 return result;
 }

 /**
 * Checks for the presence of a t or rt directive on the same line. Returns
 * true if the right trim directive was present.
 */
 private boolean deliberateRightTrim() {
 boolean result = false;
 for (TemplateElement elem = this.prevTerminalNode(); elem != null
 && elem.endLine == this.beginLine; elem = elem
 .prevTerminalNode()) {
 if (elem instanceof TrimInstruction) {
 TrimInstruction ti = (TrimInstruction) elem;
 if (!ti.left && !ti.right) {
 result = true;
 }
 if (ti.right) {
 result = true;
 int firstLineIndex = firstNewLineIndex() + 1;
 if (firstLineIndex == 0) {
 return false;
 }
 if (text.length > firstLineIndex
 && text[firstLineIndex - 1] == '\r'
 && text[firstLineIndex] == '\n') {
 firstLineIndex++;
 }
 char[] trailingPart = substring(text, firstLineIndex);
 char[] openingPart = substring(text, 0, firstLineIndex);
 if (trim(openingPart).length == 0) {
 this.text = trailingPart;
 this.beginLine++;
 this.beginColumn = 1;
 } else {
 int lastNonWS = openingPart.length - 1;
 while (Character.isWhitespace(text[lastNonWS])) {
 lastNonWS--;
 }
 char[] printablePart = substring(text, 0, lastNonWS + 1);
 if (trim(trailingPart).length == 0) {
 // THIS BLOCK IS HEINOUS! THERE MUST BE A BETTER
 // WAY! REVISIT (JR)
 boolean trimTrailingPart = true;
 for (TemplateElement te = this.nextTerminalNode(); te != null
 && te.beginLine == this.endLine; te = te
 .nextTerminalNode()) {
 if (te.heedsOpeningWhitespace()) {
 trimTrailingPart = false;
 }
 if (te instanceof TrimInstruction
 && ((TrimInstruction) te).left) {
 trimTrailingPart = true;
 break;
 }
 }
 if (trimTrailingPart)
 trailingPart = EMPTY_CHAR_ARRAY;
 }
 this.text = concat(printablePart, trailingPart);
 }
 }
 }
 }
 return result;
 }

 /*
 * private String leftTrim(String s) { int i =0; while (i<s.length()) { if
 * (!Character.isWhitespace(s.charAt(i))) break; ++i; } return
 * s.substring(i); }
 */
 private int firstNewLineIndex() {
 String content = new String(text);
 int newlineIndex1 = content.indexOf('\n');
 int newlineIndex2 = content.indexOf('\r');
 int result = newlineIndex1 >= 0 ? newlineIndex1 : newlineIndex2;
 if (newlineIndex1 >= 0 && newlineIndex2 >= 0) {
 result = Math.min(newlineIndex1, newlineIndex2);
 }
 return result;
 }

 private int lastNewLineIndex() {
 String content = new String(text);
 return Math.max(content.lastIndexOf('\r'), content.lastIndexOf('\n'));
 }

 /**
 * figures out how many opening whitespace characters to strip in the
 * post-parse cleanup phase.
 */
 private int openingCharsToStrip() {
 int newlineIndex = firstNewLineIndex();
 if (newlineIndex == -1 && beginColumn != 1) {
 return 0;
 }
 ++newlineIndex;
 if (text.length > newlineIndex) {
 if (newlineIndex > 0 && text[newlineIndex - 1] == '\r'
 && text[newlineIndex] == '\n') {
 ++newlineIndex;
 }
 }
 if (new String(text).substring(0, newlineIndex).trim().length() > 0) {
 return 0;
 }
 // We look at the preceding elements on the line to see if we should
 // strip the opening newline and any whitespace preceding it.
 for (TemplateElement elem = this.prevTerminalNode(); elem != null
 && elem.endLine == this.beginLine; elem = elem
 .prevTerminalNode()) {
 if (elem.heedsOpeningWhitespace()) {
 return 0;
 }
 }
 return newlineIndex;
 }

 /**
 * figures out how many trailing whitespace characters to strip in the
 * post-parse cleanup phase.
 */
 private int trailingCharsToStrip() {
 String content = new String(text);
 int lastNewlineIndex = lastNewLineIndex();
 if (lastNewlineIndex == -1 && beginColumn != 1) {
 return 0;
 }
 String substring = content.substring(lastNewlineIndex + 1);
 if (substring.trim().length() > 0) {
 return 0;
 }
 // We look at the elements afterward on the same line to see if we
 // should strip any whitespace after the last newline
 for (TemplateElement elem = this.nextTerminalNode(); elem != null
 && elem.beginLine == this.endLine; elem = elem
 .nextTerminalNode()) {
 if (elem.heedsTrailingWhitespace()) {
 return 0;
 }
 }
 return substring.length();
 }

 boolean heedsTrailingWhitespace() {
 if (isIgnorable()) {
 return false;
 }
 for (int i = 0; i < text.length; i++) {
 char c = text[i];
 if (c == '\n' || c == '\r') {
 return false;
 }
 if (!Character.isWhitespace(c)) {
 return true;
 }
 }
 return true;
 }

 boolean heedsOpeningWhitespace() {
 if (isIgnorable()) {
 return false;
 }
 for (int i = text.length - 1; i >= 0; i--) {
 char c = text[i];
 if (c == '\n' || c == '\r') {
 return false;
 }
 if (!Character.isWhitespace(c)) {
 return true;
 }
 }
 return true;
 }

 boolean isIgnorable() {
 if (text == null || text.length == 0) {
 return true;
 }
 if (!isWhitespace()) {
 return false;
 }
 // trick here
 boolean atTopLevel = true;
 TemplateElement prevSibling = previousSibling();
 TemplateElement nextSibling = nextSibling();
 return ((prevSibling == null && atTopLevel) || nonOutputtingType(prevSibling))
 && ((nextSibling == null && atTopLevel) || nonOutputtingType(nextSibling));
 }

 private boolean nonOutputtingType(TemplateElement element) {
 return (element instanceof Macro || element instanceof Assignment
 || element instanceof AssignmentInstruction
 || element instanceof PropertySetting
 || element instanceof LibraryLoad || element instanceof Comment);
 }

 private static char[] substring(char[] c, int from, int to) {
 char[] c2 = new char[to - from];
 System.arraycopy(c, from, c2, 0, c2.length);
 return c2;
 }

 private static char[] substring(char[] c, int from) {
 return substring(c, from, c.length);
 }

 private static char[] trim(char[] c) {
 if (c.length == 0) {
 return c;
 }
 return new String(c).trim().toCharArray();
 }

 private static char[] concat(char[] c1, char[] c2) {
 char[] c = new char[c1.length + c2.length];
 System.arraycopy(c1, 0, c, 0, c1.length);
 System.arraycopy(c2, 0, c, c1.length, c2.length);
 return c;
 }

 boolean isWhitespace() {
 return text == null || trim(text).length == 0;
 }

}

  • Now if you run the web application you will see the upload page.
  • Next step is to configure the GaeFileUploadInterceptor in struts.xml file.In struts 2, file upload is done by FileUploadInterceptor which intercept all the MultiPartRequest and provides the File object to the action. Then action does what ever it wants to do with the File object.But, on google app engine you can’t get the File object because file writes and many other file related operations are not allowed on GAE.So, we will use GaeFileUploadInterceptor which provides a String object which contains all the file content.You can save this string as a blob into the datastore or convert this string object into InputStream and return to the user.You need to add an entry in struts.xml for GaeFileUploadInterceptor.
</pre>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="struts-default.xml"></include>
<package name="" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="gaeFileUploadInterceptor"
class="com.struts2.gae.interceptor.GaeFileUploadInterceptor" />
<interceptor-stack name="fileUploadStack">
<interceptor-ref name="gaeFileUploadInterceptor"></interceptor-ref>
<interceptor-ref name="basicStack"></interceptor-ref>
</interceptor-stack>
</interceptors>

<default-interceptor-ref name="fileUploadStack" />
<action name="add">
<result>/upload.jsp</result>
</action>
</package>

</struts>
<pre>
  • Next step is to create the UploadAction which will handle the upload request.

package com.fileupload;

import java.io.InputStream;

import org.apache.commons.io.IOUtils;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {

 private static final long serialVersionUID = -300329750248730163L;
 private String photo;
 private String photoContentType;
 private String photoFileName;
 private InputStream photoStream;

 public String upload() throws  Exception {
 photoStream = IOUtils.toInputStream(photo,"ISO-8859-1");
 return "success";
 }

 public String getPhoto() {
 return photo;
 }

 public void setPhoto(String photo) {
 this.photo = photo;
 }

 public String getPhotoContentType() {
 return photoContentType;
 }

 public void setPhotoContentType(String photoContentType) {
 this.photoContentType = photoContentType;
 }

 public String getPhotoFileName() {
 return photoFileName;
 }

 public void setPhotoFileName(String photoFileName) {
 this.photoFileName = photoFileName;
 }

 public InputStream getPhotoStream() {
 return photoStream;
 }

 public void setPhotoStream(InputStream photoStream) {
 this.photoStream = photoStream;
 }
}

If you notice there are three properties in the action photo,photoContentType,photoFileName.These properties get their values from the GaeFileUploadInterceptor. These properties have to start with name you gave the file in the upload.jsp <s:file name=”photo” label=”Upload new Photo”></s:file>. In this, name is “photo” so you will get your file content in a property called photo and the two other properties will start with photo.

The second thing to notice is that result of action is “success” which is not SUCCESS you normally use. In this we are using a different result type called org.apache.struts2.dispatcher.StreamResult. Stream result is a custom Result type for sending raw data (via an InputStream) directly to the HttpServletResponse.

  • Now we will configure UploadAction in struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
 <include file="struts-default.xml"></include>
 <package name="" namespace="/" extends="struts-default">
 <interceptors>
 <interceptor name="gaeFileUploadInterceptor"
 class="com.struts2.gae.interceptor.GaeFileUploadInterceptor" />
 <interceptor-stack name="fileUploadStack">
 <interceptor-ref name="gaeFileUploadInterceptor"></interceptor-ref>
 <interceptor-ref name="basicStack"></interceptor-ref>
 </interceptor-stack>
 </interceptors>

 <default-interceptor-ref name="fileUploadStack" />
 <action name="add">
 <result>/upload.jsp</result>
 </action>
 <action name="upload" method="upload">
 <result name="success" type = "stream">
 <param name="contentType">image/jpeg</param>
 <param name="inputName">photoStream</param>
 <param name="contentDisposition">filename="photo.jpg"</param>
 <param name="bufferSize">1024</param>
 </result>
 </action>
 </package>

</struts>

  • Finally, Run this application you will be able to upload the photo and then view it in your browser.

In this blog, i have tried to explain you how you can do file upload using struts 2 on google app engine.Please make sure you download the struts2-gae jar.Hope this helps you all.

You can dowload the sample project from here.

Does Java Puzzlers make Good Interview Questions?

Intent of my Blog

Recently i wrote an blog entry on one of the java puzzlers that was asked to me in an interview.I received some of the comments which said this is unfair to ask java puzzlers in an interview.So i thought of writing an blog which discusses whether java puzzlers make good interview questions or not.

Does Java Puzzlers make Good Interview Questions?

I think before answering this question that should we ask java puzzlers in an interview or not we need to define some guidelines about what makes a good interview question. And if java puzzlers fit within those guidelines then we can ask the them in an interview.I am giving my personal point of view please add in your comments if you think something different.

Guideline for a Good Technical Interview Question

  1. Question should be How not what = Should be Practical which means that Interviewer should not ask the definition of some term or concept the interview question should be such that it discusses  practical application of concept.Asking how has the advantage that interviewer gets the correct feedback about interviewee that interviewee actually understand the concept.
  2. Question should be on simpler concepts = Asking a difficult question doesn’t make an interview question good.In my personal opinion interview question should be about the concepts which a developer normally use. You can vary the difficulty level of question depending upon position you are hiring but the concept should be simple.For example you can ask questions on overriding which can be simple or difficult but the concept of overriding is such that every java developer should know.
  3. Question can be Extended =  A good interview question should be such that you can build your interview on that question which means that if you ask a question on overriding you can start with the easier question and then build your interview by asking questions that increases in difficulty.
  4. Question should not be specific to API = The question that i mentioned in my post was good but it was specific to the HashSet remove method arguments. Let me explain, when you create an hashset  like HashSet<Short> s = new HashSet<Short>() you might expect that when you are doing s.remove(i-1) should remove only short objects but when you take a look at the remove method it takes Object .This is something specific to api which  most of the developers might not know. So asking such a question becomes useless.
  5. Question should provide a learning point = A good interview question should provide a value add to the interviewee. It might be possible that interviewee knows everything which is great and you can hire him/her. But even if he/she doesn’t know the answer they can at least  learn a good technical point.

Does java puzzlers fit these guidelines?

In my view java puzzler fit some of the guidelines:-

  1. All Java Puzzler are about How not What so java puzzlers can provide interviewer the practical understanding of the interviewee.
  2. Java Puzzlers are about simpler concepts but the Puzzlers are not simple because they discuss the trap or corner cases of the API. You can use these concepts for interviews but the questions are very specific to api and most of the times should not be asked in interview.
  3. Java Puzzlers can be extended but again because they are not easy most of the times you will not get the correct answer.
  4. Java Puzzlers are specific to API and they require very good understanding of java api.
  5. Java Puzzlers definitely provide a learning value to interviewee because these questions touches the corner cases  of the api which normally developers doesn’t know.

Conclusion

In my view you can ask some of the java puzzlers in an interview as java puzzlers definetly provide a value. Sometimes you should only take a concept and build you question on that and sometime take the whole question. If you think the java puzzler you are asking is difficult and a normal developer who hasn’t read java puzzlers book can’t answer please dont make that question a decider question means your decision to hire a person should not be based only on  java puzzler. Java Puzzlers are definetly very good questions and you should use them wisely in interview.

These are some of my view points. Please share your also.

Java Puzzlers are asked in interviews

Intent of my Blog

This blog is about one of the question that i was asked in an interview two years back. I forgot this question but yesterday i again faced this question and this is a “java puzzler”.

Question

Yesterday while looking for videos on “java puzzlers” i found out link on youtube by Joshua Bloch.When i started viewing this video one of the puzzle reminded of a question i was asked in an interview two years back. Although this question is not in Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases but it is one of the question i thought worth sharing.Try this question and have fun.

public class JavaPuzzler{
    public static void main(String[] args) {
        HashSet<Short> s = new HashSet<Short>();//1
        for(short i = 0; i<100;i++){//2
            s.add(i);//3
            s.remove(i-1);//4
        }
        System.out.println(s.size());//5
    }
}

Before viewing the answer of this question please try guessing the answer to this question and then run code in eclipse to check whether you what you were thinking matches the answer.If the answer amaze you it is a java puzzler.

Answer

Answer of this puzzler is 100.

To understand why we get 100 as answer lets try to understand the code line by line.

In line 1 we created an HashSet which is of type java.lang.Short .

In line 2 we are doing a for loop

In line3 we are adding short primitive which will be autoboxed to Short object  to the HashSet Collection.

In line 4, we are trying to remove an element from HashSet, which we added just before the current element. But there is a small gotcha (can you guess what is it?), the gotcha is when we do s.remove(i-1),  first of all expression (i -1) is evaluated in which short is widened to int and then int is converted to Integer object. This is due to autoboxing in java 1.5 version.If you look into the javadoc of remove method of HashSet, you will find that it takes an Object, so you can remove Integer objects  from HashSet of Short objects, but this will not work as a result none of the Short objects will get removed.

So in line 5 we get output as 100.

Hope you find this puzzle interesting, i will strongly recommend viewing this presentation.

You can share any of yours interview question which you think is a “java puzzler”.

Interim build to testing team worked for us

Intent of my blog

This blog is about my personal experience of giving interim build to QA team. So far now it has worked great for us.

Content

Few months back my team decided that we will be following some agile practices. So we decided to list down the practices that we will follow.We tried tdd but it failed. The only practice from that list which we have successfully followed is giving interim build to testing team during an iteration.
We follow 1 month iteration of which 3 weeks is for development and 1 week for testing. Till few months we give build to QA team only when we have done all development which means 3 weeks they were not doing any testing but were creating test scenarios and understanding user stories.As we were not following tdd ,during the testing lot of bugs were raised which were programmatic error like NullPointerException or sometimes the understanding of user story was different which leads to QA week to be  a very tiring week(fixing lot of defects).Also this also leads to lot of tension and pressure on the team.

Interim Build became the SilverBullet

From the last few iterations we have started giving interim build to QA usually one or two between the development cycle.This has helped our team a lot:-

  1. Programmatic errors are resolved during the development cycle so cost of fixing the defect is quite low.
  2. Testing Team is doing testing during the development cycle.It helps testing team in understanding the application better rather than just reading documentation.
  3. Quality of defects raised by QA team during the QA week increased because they were able to do more functional testing rather than finding NullPointerException or validation issues.
  4. Pressure on developers and QA team reduced during the QA cycle.
  5. High Quality of Application

These are some of the benifits which we got by giving interim builds to QA team.

Please share your thoughts also.

Java Puzzlers are found in day to day work

Intent of my Blog

Today i was writing a piece of code and found one java puzzle. When i debugged it, i remembered that i read it something like this when i was reading  Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases .

Java Puzzle

Today while doing my day to day office work i found one java puzzle which i thought was worth writing.

Can you guess what is the output of following  java code:-

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] arr = {"java ","puzzlers ","is ","a ","good ","book"};
		String message = null;
		for(String str : arr){
			message += str;
		}
		System.out.println(message);
	}

}

I am posting the answer as well as the solution to overcome this problem.But first try this java puzzler yourself.Run this piece of code in eclipse and see what you guessed is correct.

Answer
If you ran this code you will get nulljava puzzlers is a good book
but you might be thinking that it should print java puzzlers is a good book If you don’t know that when you are concatenating the string null is taken as a string and was appended to the result . + operator is overridden for string so it does the concatenation for you.

The Easiest Solution to this problem can be initializing message with empty string rather than null.

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] arr = {"java ","puzzlers ","is ","a ","good ","book"};
		String message = "";// replacing null with empty string
		for(String str : arr){
			message += str;
		}
		System.out.println(message);
	}

}

But this solution also has a problem and that problem is related to performance because when you are iterating over array you are doing String using concatenation in a loop. In each iteration, the String is converted to a StringBuffer/StringBuilder, appended to, and converted back to a String.This can lead to decrease in performance of your program.
The best solution is the use of StringBuilder class.

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] arr = {"java ","puzzlers ","is ","a ","good ","book"};
		StringBuilder message =  new StringBuilder();
		for(String str : arr){
			message.append(str);
		}
		System.out.println(message.toString());
	}

}

If you think there is anyother better solution please put that in comment.

Does Google Search limits the developer ability to solve problems?

Intent of my blog

I am trying to express my views on the problem which i think google search pose to developers in terms of limiting the ability of software developer to solve problems.May be my point of view is totally irrelevant to many of you but i think getting every answer at the click of just one google search button leads to under-utilized brain.

Approach

In my personal day to day work whenever i am struck with some problem and i think i just can’t think more i just do a google search and try to find the solution to my problem. If the solution which i get by viewing the first few links(which we all normally do 🙂 ) on google search page are relevant to my problem i will integrate(after understanding the solution) that piece of solution in my code and move to the next step/task.

Problem with this Approach

  1. Easy way to get solution :- Once you know that you can find every solution to your problem by googling it becomes a habit and most of the time without giving proper thought or applying your mind you just do google search.
  2. Brain not optimally used:- Because more than often we are relying on search results to give us the solution to our problems we tend to let search engine become our brain and leaving the brain we have do nothing.
  3. Lazy Developers :- This also leads to developers becoming lazy in solving there problems themselves.
  4. Solution doesn’t work as expected:- Because you are not giving your 100% in finding the solution to your problem leads to the another problem that you have not fully understood your problem  and the solution you found by googling was just a partial or incomplete or even wrong solution.
  5. Time Waste :- It happens that you try to put time on solution which are not the actual solution to the problem leading you to tweaking the piece of code to work the way you want and finally if it doesn’t work you just delete the whole piece of code and start thinking in a better way.

Above mentioned are few of my concerns that i can think right now but i think there will be many.

Please share your thoughts also even if you think what i am saying is totally rubbish 🙂

Why my attempt to apply tdd failed?

Intent of my Blog

The intent of this blog is to write down the reasons for my failure to apply test driven development in my current project. Uncle Bob Martin in his interview on infoq said that “Developer is not professional if he does not practice test driven development”. We tried following tdd but failed (are we not professionals 😦 )!!

Brief Background

We had a major release few months back and till that time we were not following Test Driven Development so when the talks for the subsequent releases started we thought that we should follow tdd.I was given the responsibility to come up with strategy on how we will be applying tdd in our project. So i started with reading kent beck book Test Driven Development: By Example. I also read lots of articles  on infoq and testdriven.com to get a good and thorough understanding of tdd and was convinced that we should apply “TDD”.I gave a presentation-cum-coding demo to my team and after my demo we all were convinced that we will be applying TDD.

Ist Iteration using TDD :-Whenever you start some new thing you are excited, the same was the case with us.So before writing any class or any piece of code we used to write a test for the same. We were developing our code in an incremental manner, letting the design evolve as tdd gurus says and we were seeing small benefits like fixing programming errors like NullPointerException were caught in the early stages before the code goes to the QA team for testing.
For the next two weeks i was on leave and when i came Iteration 2 had started and tdd was no where…. So what went wrong………………

I asked my team why now we are not using tdd and the answer was that client changed the contract of one the web service that we published in iteration 1 although we had taken the feedback from him on the previous contract but somehow later he felt that this was not correct and we have to re-implement the web service with new contract and because of pressure of time we commented out all the tests and wrote the code without tests.

I started thinking about our failure to apply tdd because i think time pressure is not the only reason why teams fail to apply tdd there are many reasons. So i am writing down some reasons(in no particular order) which i think led to us not apply tdd:-

  1. Time:- Developers think that writing test cases before writing code requires more time and most often under pressure circumstances time is more important than writing test cases.
  2. Boring to write test cases first:– Its very difficult to get into the habit of writing test first than code so developers are reluctant to write test first.
  3. Client Support:- When we told our client that we will be applying tdd in our code, the response was that tdd doesn’t provide better results and in a longer run developers don’t maintain the test and they become irrelevant after some iteration.Client cares about money not test cases.
  4. Writing Exhaustive test cases :- I think tdd will make sense when you are able to cover most of the scenarios in your test class. More often what happens is that developers just write the basic test and test class doesnt evolve to incorporate all the test cases as a result developer thinks that when the number of bugs getting raised is not decreasing why should i write test.
  5. Patience :- I think it is very important that we should not expect everything to go fine and everyone to become tdd guru in one iteration. So we should give tdd few iterations before we can judge whether its useful or not.
  6. Poor Examples :- The example with which tdd is often taught are very simple as compared to the one you face in real life scenarios.So it becomes difficult to follow tdd when there is some real complex problem come.
  7. Legacy Code

In short, i can say that applying tdd requires a complete change in mindset you have start fresh.These are some of the reasons that i could think of at this point of time why applying tdd failed.
Please share your views also.