September 29, 2014

Lifecycle of a JSP- part I



JSPs are basically dynamic HTML pages, the dynamic content being provided by specific libraries(JSTL or Java Standard Tag Libraries ) expressions and directives ( page,import,include ). The specifics of these elements I will discuss in future posts.

This post will deal with the life-cycle of a JSP  in Apache Tomcat. The questions that will be answered will be
  • Does a JSP get converted in .java file. If so,when ? during server start-up or every time a JSP page is requested by the browser.
  • Which component of Tomcat does the conversion? Where does this so call JSP engine reside in Tomcat?
  • What happens after the conversion ? Where do the converted files reside ? 
  • When does a JSP page finally get destroyed ?
  • Dynamic and Static inclusion


So let's begin with answering the first question:

Yes. A JSP page gets  translated into a Servlet java file and corresponding class file.This is known as the translation & compilation phase. 

e.g. login.jsp --> login_jsp.java --> login_jsp.class

The java and class files are stored in 'work' directory in Tomcat

Now, these 2 phases can happen when the application is deployed. The container translates & compiles all jsp into class files. This is called pre-compilation and provides better performance since time is not spent during page request.

But these 2 phases can also happen when a request for jsp is made. The container checks if the jsp file is newer than the class file. if it is, then it translates & compiles again before serving the request.

Sometimes, a jsp file needs to be included into another jsp file. This can be done by

<%@include directive or <jsp:include action

The difference b/w the two is that using the former, the jsp gets included into its parent jsp during application deployment & hence is  best suited for including static content. That's why only relative path w.r.t the parent jsp is enough for inclusion e.g

<%@include file="./footer.jsp" %>   if parent jsp and footer.jsp are in same directory.

Using the latter,the jsp gets included during request time i.e. when the client requests the parent jsp file. This is called dynamic inclusion and is suited for jsp with lot of dynamic content. This include action also can cause performance overhead since inclusion happens at run time. So use it wisely i.e.for including jsp with a lot of dynamic content.

Also, since inclusion happens at run time, the context relative path is used.

<jsp:include page=/XXX/footer.jsp />  if footer.jsp is present in dir 'XXX' of the web-application

July 30, 2014

page redirect in Javascript


JavaScript Location Object also have these three methods
  1. assign() -- Loads a new document.
  2. reload() -- Reloads the current document.
  3. replace() -- Replaces the current document with a new one
You can use assign() and replace methods also to redirect to other pages like these
window.location.assign("http://www.stackoverflow.com");

window.location.replace("http://www.stackoverflow.com");
The difference between replace() and assign()  is that replace() removes the URL of the current document from session history, means it is not possible to use the "back" button to navigate back to the original document. So use the assign() method if you want to load a new document, and also want to navigate back to the original document.
Apart from the above,
window.location.href = "http://stackoverflow.com";
This is basically simulating the click of a link

Reference

July 25, 2014

A few good men :)

The talented Jack Nicholson stole the show with this dramatic monologue from "A Few Good Men" -  https://www.youtube.com/watch?v=9FnO3igOkOk


Here 's a tribute to one of my all-time favorite movie monologues.

Developer: You want answers?

Product Manager: I think I'm entitled to them.

Developer: You want answers?

Product Manager: I want the truth!


Developer: You can't handle the truth! we live in a world that has software applications. And those applications have to be developed by men with coding skills. Who's gonna do it? You? I have a greater responsibility than you can possibly fathom. You weep for deadlines and you curse the developers. You have that luxury. You have the luxury of not knowing what I know: that missing the deadlines, while tragic, probably improved code quality. And my existence, while grotesque and incomprehensible to you, improved code quality...You don't want the truth. Because deep down, in places you don't talk about at scrum meetings, you want me on that sprint. You need me on that sprint.

We use words like SOLID,KISS,DRY...we use these words as the backbone to a life spent developing something. You use 'em as a punchline. I have neither the time nor the inclination to explain myself to a man who presents and takes credit for the product that I develop, then questions the manner in which I develop it! I'd rather you just increased my salary and went on your way. Otherwise, I suggest you pick up a laptop and write code. Either way, I don't give a damn what you think you're entitled to!!

Product Manager:  Did you break the code ?

Developer: (quietly) I wrote the code as per the design.

Product Manager: Did you break the code ?

Developer: You're goddamn right I did!!

July 24, 2014

LinkageError: loader attempted duplicate class definition for name - 1



I have encountered this error on a Spring 4.0.5 + Hibernate 3 or 4 application.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'FMDao' defined in file [D:\apache-tomcat-7.0.34\webapps\mwas\WEB-INF\classes\com\mwas\datalayer\dao\FMDao.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.mwas.datalayer.dao.FMDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is
org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
.
.
.  
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.mwas.datalayer.dao.FMDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:494)  
.
.
.
at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.CglibAopProxy.createProxyClassAndInstance(CglibAopProxy.java:227)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:66)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
... 36 more
.
.
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 41 more
Caused by: java.lang.LinkageError: loader (instance of  org/apache/catalina/loader/WebappClassLoader): attempted  duplicate class definition for name: "com/mwas/datalayer/dao/FMDao$$EnhancerBySpringCGLIB$$41240c1b"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)


After a lot of trial & error, I found that in order to integrate Hibernate with Spring 4.0.5, the following needs to be done

1. Add spring-orm 4.0.5 in your classpath or pom.xml ( if you are using Maven)
2. Add hibernate-core for release 3 or 4 in classpath or pom.xml.
3. Add cglib-nodep 3.1 in classpath or pom.xml

These steps should take care of the dependencies for Spring +t Hibernate integration.

Now, define the LocalSessionFactoryBean & HibernateTransactionManager in your Sprinconfiguration xml based on the hibernate version you intend to use. for e.g. for Hibernate 3, define

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
.
.
</bean>
<bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
 </bean>

I encountered this error on a DAO class, annotated by @Repository.  One important step I took  in order to fix this error was to make the class implement an interface. This is weird, huh b'coz as per Spring docs, from 3.2 version CGLIB aop proxy creation don't require the target class to implement an interface


Need to investigate this further!!!

July 01, 2014

InterruptedException




http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

Interesting article on understanding
1. Thread Interruption
2. Handling InterruptedException  in Cancelable and NonCancellable scenarios.


A StackOverflow discussion on the same

http://stackoverflow.com/questions/3976344/handling-interruptedexception-in-java