Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Tuesday, November 5, 2013

Upgrade from Hibernate to Spring with HibernateDaoSupport

There is a program has already implementing Hibernate as its natural implementation when retrieving data from database. At the very first glance on the code, it’s very clean. Code snippet below is the main function of the program, this function hold an instance of BookDao.
 public static void main(String args[]) {

  BookDao bookDao = new BookDao();
  
  List< book > bookList = bookDao.readAll();
  
  if( bookList == null ) {
   System.out.println("No book records found");
  }
 }
The BookDao has a readAll() that retrieve the data from database and return the book list back to the main function.
public class BookDao {
 public List< book > readAll() {
  
  List< book > bookList = null;
  Session session = SessionManager.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  bookList = session.createQuery("from Book").list();

  return bookList;
 }
 ...
 ...
}
This is the Hibernate mapping of the book entity. It is pretty straight forward.

 
  
   
  
  
  
  
  
 

Well, not much nonsense in this program. In one day, there is a requirement to integrate this DAO with Spring framework. Things start to get complicated, in the same time more code to write.

Step 1 – I need to have a data source bean configure in Spring. Pump in all the required information into this bean to bridge my program and my desire database, in my case is MYSQL.
 
  
  
  
  
 
Step 2 – I need to have a sessionFactory bean configure in Spring because the DAO will need this bean to initialize the session in Spring. Port over the data source declares in Step 1 to tell which connection that this session will hold.
 
  
   
  
  
  
   
    org.hibernate.dialect.MySQLInnoDBDialect
    org.hibernate.hql.ast.ASTQueryTranslatorFactory
    100
    false
    auto
    thread
    false
    false
    true
    true
   
  
  
  
   
    Book.hbm.xml
   
  
 
Step 3 - Revamp BookDao to extends HibernateDaoSupport. Note on the remark at (1), the session is came from the sessionFactory declare in step 2. Also take note that I’m no longer call beginTransaction() in order to execute the query.
public class BookDao extends HibernateDaoSupport {
 
 public List< Book > readAll() {
  List< Book > bookList = null;
  Session session = getSession();    // (1)
  bookList = session.createQuery("from org.huahsin.Book").list();
  
  return bookList;
 }
 ...
 ...
}
Step 4 – Inject the sessionFactory bean into DAO. This is to tell DAO which session and connection will be use to communicate to database.
 
  
 
Take note that if the sessionFactory is not injects into DAO in this step, when this BookDao bean is first load. Following error would be seen immediately.
Caused by: java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
 at org.springframework.orm.hibernate3.support.HibernateDaoSupport.checkDaoConfig(HibernateDaoSupport.java:118)
 at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1479)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1419)
 ... 12 more
Last but not least, the hibernate.cfg.xml may throw away since it is not needed anymore. This is all about the work need to be done when migrate to Spring’s HibernateDaoSupport.

Sunday, October 20, 2013

Return immediately after exception has been capture.

I was being captured by exception. You know what? I miss out the very important point on Exception Handling in JAVA. Let’s take a look on the code below:
public static void main(String args[]) {
 System.out.println("Before Exception");
 
 try {
  System.out.println("Before throw");
  System.out.println(args[1]);          // (1)
  System.out.println("After throw");
 }
 catch( Exception e ) {
  System.out.println(e);                // (2)
 }
 finally {
  System.out.println("Cleaning resources");
 }
 
 System.out.println("After Exception");    // (3)
}
When there is an exception error on (1), immediately (2) will get invoked. Somehow the code will never stop executing after (2) and will continue its execution until (3). This could lead to a disaster if subsequent implementation is highly depends on the process in try block. Thus to play it safe, return the code immediately if exception is being capture in the catch block. No worry on the finally block because the code will still execute giving me a chance to clean up my resources.

ReferenceError: "myfaces" is not defined.

I was running a Blackbox unit testing on a page consisting of JSF page using Selenium 2. If I were to use FirefoxDriver to run the test, the test completed successfully. But if I run the test using HtmlUnitDriver, it will fail and following error would be seen.
java.lang.RuntimeException: org.openqa.selenium.WebDriverException: com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "myfaces" is not defined.
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_30'
Driver info: driver.version: HtmlUnitDriver
 at com.anteambulo.SeleniumJQuery.jQueryFactory.js(jQueryFactory.java:124)
 at com.anteambulo.SeleniumJQuery.jQuery.js(jQuery.java:608)
 at com.anteambulo.SeleniumJQuery.jQuery.jsref(jQuery.java:612)
 at com.anteambulo.SeleniumJQuery.jQuery.click(jQuery.java:226)
 at org.huahsin.authentication.ForgotPassword.testEmptyLoginId(ForgotPassword.java:32)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
 at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.openqa.selenium.WebDriverException: com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "myfaces" is not defined.
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_30'
Driver info: driver.version: HtmlUnitDriver
 at org.openqa.selenium.htmlunit.HtmlUnitDriver.executeScript(HtmlUnitDriver.java:497)
 at com.anteambulo.SeleniumJQuery.jQueryFactory.js(jQueryFactory.java:115)
 ... 29 more
Caused by: com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "myfaces" is not defined.
 at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:669)
 at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:601)
 at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
 at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:601)
 at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:576)
 at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.java:1005)
 at org.openqa.selenium.htmlunit.HtmlUnitDriver.executeScript(HtmlUnitDriver.java:491)
 ... 30 more
Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "myfaces" is not defined.
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3603)
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3587)
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.notFoundError(ScriptRuntime.java:3657)
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.java:1749)
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.name(ScriptRuntime.java:1690)
 at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1622)
 at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798)
 at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
 at com.gargoylesoftware.htmlunit.javascript.host.EventHandler.call(EventHandler.java:81)
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.applyOrCall(ScriptRuntime.java:2378)
 at net.sourceforge.htmlunit.corejs.javascript.BaseFunction.execIdCall(BaseFunction.java:304)
 at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:89)
 at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1531)
 at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798)
 at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
 at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:405)
 at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:275)
 at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3031)
 at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:103)
 at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.java:594)
 at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:654)
 ... 36 more

As I search through the documentation, the default JavaScript engine of HtmlUnitDriver is from Rhino. Somehow not every browser following the same standard and have their very own version of implementation on JavaScript.

This is the text extract from the documentation:
When we say "javascript" we actually mean "javascript and the DOM". Although the DOM is defined by the W3C each browser out there has its own quirks and differences in their implementation of the DOM and in how javascript interacts with it. HtmlUnit has an impressively complete implementation of the DOM and has good support for using javascript, but it is no different from any other browser: it has its own quirks and differences from both the W3C standard and the DOM implementations of the major browsers, despite its ability to mimic other browsers.
To fix this issue, a true parameter need to be pass in to the constructor of HtmlUnitDriver as shown below. This is to mimic the JavaScript version running on Internet Explorer.
   ...
   new HtmlUnitDriver(true);
   ...

Tuesday, October 15, 2013

Why SimpleGrantedAuthority cannot be resolve to a type?

I am using Spring Security 3.0.8, and have the following code:
    public class MyAuthServiceProvider implements UserDetailsService {
        ...
        ...
        public static List< GrantedAuthority > getGrantedAuthorities(List< String > roles) {
         List< GrantedAuthority > authorities = new ArrayList< GrantedAuthority >();
         for( String role:roles ) {
          authorities.add(new SimpleGrantedAuthority(role));
         }
         return authorities;
        }
    }
As mention in the title, SimpleGrantedAuthority couldn't be resolve. There are 2 solutions on this, the first one is to replace SimpleGrantedAuthority with GrantedAuthorityImpl as shown below:
    ...
    authorities.add(new GrantedAuthorityImpl(role));
    ...
The second one is to replace SimpleGrantedAuthority with SwitchUserGrantedAuthority, but I need to implements AuthenticationProvider. I refuse this solution because I feel that (correct me if I'm wrong) this doesn't sound right for MyAuthServiceProvider to implement AuthenticationProvider and UserDetailsService at the same time.

I'm sure I have include spring-security-core library in MAVEN. May I know what else was missing causing this error on SimpleGrantedAuthority? It has been confusing me for a long time, now I got the answer. SimpleGrantedAuthortiy is a replacement of GrantedAuthorityImpl, and this class will be deprecated in Spring Security 3.1. In addition, both of this class are implementing GrantedAuthority, have a look here for SimpleGrantedAuthority and GrantedAuthorityImpl. Thus it has no issue since both of them implementing the same function.

To conclude this, since I'm using version 3.0, then I am safe to use GrantedAuthorityImpl class.

Monday, October 7, 2013

How to handle commandLink in Selenium 2?

My initial assumption on the link is constructed using <a href...="">. Thus when I initiate my test using following code, it was failed unexpectedly.
WebElement clickMe = webDriver.findElement(By.partialLinkText("Click Me"));
clickMe.click();
Why this happened? I have double verify on my code, it just looking fine. But when I view the page’s source, I got the following code in my mind.

    Click Me

Doesn’t it sound funny? Consider the page was build using JSF and the link is construct using commandLink in JSF like this:


I wasn’t sure the background on how JSF is render on the browser. But one thing I am sure is the link has JavaScript. Without further ado, my temporary solution is to workaround the JavaScript using third party library called SeleniumJQuery. It is quite straight forward to use and pretty simple, to click on the link containing JavaScript, do this code:
jQueryFactory jq = new jQueryFactory();
jq.setJs(webDriver);

WebElement clickMe = webDriver.findElement(By.partialLinkText("Click Me"));
jq.query(clickMe).click();
It will work like charm.

AnnotationConfiguration is deprecated?

The SessionManager utility class is the famous one among JAVA programmer who has been working with Hibernate.
public class SessionManager {

 private static final SessionFactory sessionFactory = buildSessionFactory();
 
 private static SessionFactory buildSessionFactory() {
  
  try {
   return new AnnotationConfiguration().configure().buildSessionFactory();
  }
  catch( Throwable e ) {
   
   throw new ExceptionInInitializerError(e);
  }
 }
 
 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }
}

Unfortunately, I just realize that AnnotationConfiguration has already been deprecated Since Hibernate 3.6. Do you know what is the new implementation of this class? Well, replace this with Configuration.

Sunday, September 1, 2013

'for' attribute is not defined in JSF

Great finding from my colleague. When retrieve systemout.log from WebSphere Application Server, noticed that the following warning seem to be flooding in the log.

Attribute 'for' of label component with id xxxxxxxxxxxxxxxxxxxxxx is not defined 

This warning is due to the missing of attribute 'for' in a component being called. For example,


The purpose is to let the outputlable know which component to label. For suppressing the excessive non-informational logging line, always practise to use the 'for' attribute.

Retrieve IP address from JSF

One of my requirement in audit trail module is to capture the IP address of the user accessing the web application. My web application was developed using JSF, may I know could this be done? Such an easy job, below is the code for this mission:
 HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
 String ipAddress = request.getHeader("X-FORWARDED-FOR");
 if( ipAddress == null ) {
  ipAddress = request.getRemoteAddr();
 }

web-app_3_0.xsd schema is reference from javaee



   ...
   ...
I was clueless when I first saw the above code causing an error in Deployment Descriptor. I was trying to retrieve web-app_3_0.xsd schema but I couldn’t spot the typo error in the above code. If you were me, can you spot the error? If you take a closer look, the error happened on j2ee. It was cause by my copy and paste habit.

http://java.sun.com/xml/ns/j2ee is no longer a valid URL to retrieve JAVA EE 5 (and above) schema, it is only valid for J2EE 1.4. For JAVA EE 5 (and above) schema, the URL has been update to http://java.sun.com/xml/ns/javaee.

Thursday, August 22, 2013

Log4j fillInStackTrace() show shorter info in stacktrace

private static Logger logger = Logger.getLogger(...);

try {
   ...
}
catch( Exception e ) {
   logger.error("blah blah blah", e);  // (1)

   logger.error("blah blah blah", e.fillInStackTrace());  // (2)
}
The above code got my attention as I was wonder whether (2) is more cheaper than (1)? According to the expect, there are difference between the 2. (1) will show the original position of a stack frame where the error came from whereas (2) will pop up the old stack frame by filling in the current stack frame, thus the original stack frame were gone. In addition to that, (1) is more cheaper than (2) due to fillInStackTrace() is a synchronize function, thus this will eat up some resource when filling a log.

Below is the test result when I'm using logger.error("...", e), I have this stack trace shown
ERROR 2013-08-21 09:48:18,728 [AddUserAction:129] - An error has occurred in submitUser() 
org.hibernate.HibernateException: Hibernate Exception lor
 at org.huahsin.dao.impl.UserDaoImpl.saveUser(UserDaoImpl.java:35)
 at org.huahsin.bo.impl.AdminBoImpl.addUser(AdminBoImpl.java:275)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 at $Proxy19.addUser(Unknown Source)
 at org.huahsin.AddUserAction.submitUser(AddUserAction.java:120)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.apache.el.parser.AstValue.invoke(AstValue.java:266)
 at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
 at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:70)
 at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:88)
 at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:100)
 at javax.faces.component.UICommand.broadcast(UICommand.java:120)
 at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:937)
 at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:271)
 at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1249)
 at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:675)
 at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34)
 at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
 at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1221)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:757)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:440)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:125)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:92)
 at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:97)
 at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
 at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
 at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
 at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:939)
 at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1036)
 at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:81)
 at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:930)
 at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$1.run(DynamicVirtualHost.java:253)
 at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:457)
 at com.ibm.ws.threading.internal.Worker.executeWork(Worker.java:398)
 at com.ibm.ws.threading.internal.Worker.run(Worker.java:380)
 at java.lang.Thread.run(Thread.java:662)

Next is the test result when I'm using logger.error("...", e.fillInStackTrace()), I have this stack trace shown
ERROR 2013-08-21 09:50:46,987 [AddUserAction:129] - An error has occurred in submitUser() 
org.hibernate.HibernateException: Hibernate Exception lor
 at org.huahsin.AddUserAction.submitUser(AddUserAction.java:129)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.apache.el.parser.AstValue.invoke(AstValue.java:266)
 at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
 at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:70)
 at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:88)
 at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:100)
 at javax.faces.component.UICommand.broadcast(UICommand.java:120)
 at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:937)
 at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:271)
 at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1249)
 at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:675)
 at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34)
 at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
 at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1221)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:757)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:440)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:125)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:92)
 at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:97)
 at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
 at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
 at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
 at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:939)
 at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1036)
 at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:81)
 at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:930)
 at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$1.run(DynamicVirtualHost.java:253)
 at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:457)
 at com.ibm.ws.threading.internal.Worker.executeWork(Worker.java:398)
 at com.ibm.ws.threading.internal.Worker.run(Worker.java:380)
 at java.lang.Thread.run(Thread.java:662)

Notice that (2) has much shorter stack trace. I personally prefer the (1) due to the reason I have more information on understanding the original root cause of the problem.

Saturday, August 17, 2013

Making a custom log in log4j

Never though log4j has such a deep knowledge that I didn't know of. I was assign to develop a custom made log level in log4j due to my project must follow OWASP compliance. Read the link here. Interestingly, I got the custom log level done but how could I configure it in log4j? I almost overlook on this. Anyhow this could be done in following way.

log4j.appender.APP.threshold = SECURITY#org.huahsin.util.CustomLogLevel

To log a message on security, this is the way:

logger.log(CustomLogLevel.SECURITY, "blah blah blah");

Filter specific log level in log4j configuration

Usually when I want to log something, I'll do this:
private static void Logger logger = Logger.getLogger("MyClass.class");

public void functionA() {
   log.error("blah blah blah");
}
We all knew that log4j have different log level, such as TRACE < DEBUG < INFO < WARN < ERROR < FATAL, and there are inheritance. Meaning if log4j is being configure to accept log at INFO level, the log at WARN, ERROR, and FATAL will be capture as well. How does it look like in the code?
public void functionA() {
   log.error("blah blah blah");

   ...
   ...

   log.info("ha hah hahh");
}
The above code sample will have both info log and error log being logged. If log level is set to ERROR, only "blah blah blah" will be log. Anything below ERROR log level will not be log. This is what we usually did on log4j. So what if I want to log only INFO level? I been told that log4j.additivity is for this purpose. But I failed to configure it. Anyhow I got an alternate solution, by using filter in log4j configuration.
log4j.appender.APP.threshold = info
log4j.appender.APP.filter.a=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.APP.filter.a.LevelToMatch=info
log4j.appender.APP.filter.a.AcceptOnMatch=true
log4j.appender.APP.filter.b=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.APP.filter.b.LevelToMatch=warn
log4j.appender.APP.filter.b.AcceptOnMatch=false
log4j.appender.APP.filter.b=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.APP.filter.b.LevelToMatch=error
log4j.appender.APP.filter.b.AcceptOnMatch=false
log4j.appender.APP.filter.b=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.APP.filter.b.LevelToMatch=fatal
log4j.appender.APP.filter.b.AcceptOnMatch=false
The above configuration will do the job.

Sunday, July 28, 2013

Wrong configuration in hibernate.chg.xml

This is very bad, do you know what will happened when you miss configure the hibernate configuration as the code shown below?
    username

    password


Here is the error I get when trying to establish a connection:
org.hibernate.exception.GenericJDBCException: Cannot open connection
 at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
 at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
 at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
 at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
 at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160)
 at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81)
 at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)
 at org.huahsin.dao.LoginDao.getUserByUserId(LoginDao.java:36)
 at org.huahsin.web.LoginAction.(LoginAction.java:69)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
 at java.lang.Class.newInstance0(Class.java:355)
 at java.lang.Class.newInstance(Class.java:308)
 at com.ibm.ws.jsf.config.annotation.WebSphereAnnotationLifecycleProvider.newInstance(WebSphereAnnotationLifecycleProvider.java:47)
 at org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(ManagedBeanBuilder.java:162)
 at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.createManagedBean(ManagedBeanResolver.java:303)
 at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.getValue(ManagedBeanResolver.java:266)
 at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:55)
 at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
 at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:65)
 at org.apache.myfaces.el.convert.VariableResolverToELResolver.getValue(VariableResolverToELResolver.java:116)
 at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:55)
 at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
 at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:71)
 at org.apache.el.parser.AstValue.getTarget(AstValue.java:96)
 at org.apache.el.parser.AstValue.setValue(AstValue.java:200)
 at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:425)
 at org.apache.myfaces.el.convert.ValueExpressionToValueBinding.setValue(ValueExpressionToValueBinding.java:125)
 at org.apache.myfaces.custom.updateactionlistener.UpdateActionListener.processAction(UpdateActionListener.java:154)
 at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
 at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:344)
 at javax.faces.component.UICommand.broadcast(UICommand.java:103)
 at javax.faces.component.UIData.broadcast(UIData.java:757)
 at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:937)
 at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:271)
 at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1249)
 at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:675)
 at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34)
 at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
 at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1221)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:757)
 at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:440)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:125)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:92)
 at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:97)
 at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
 at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
 at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
 at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
 at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:939)
 at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1036)
 at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:81)
 at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:930)
 at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$1.run(DynamicVirtualHost.java:253)
 at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:457)
 at com.ibm.ws.threading.internal.Worker.executeWork(Worker.java:398)
 at com.ibm.ws.threading.internal.Worker.run(Worker.java:380)
 at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.SQLException: Incorrect password or user com.informix.asf.IfxASFRemoteException: Kok.Hoe.Loh@128.230.11.83 is not known on the database server.
 at com.informix.jdbc.IfxSqliConnect.(IfxSqliConnect.java:1195)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
 at com.informix.jdbc.IfxDriver.connect(IfxDriver.java:254)
 at java.sql.DriverManager.getConnection(DriverManager.java:582)
 at java.sql.DriverManager.getConnection(DriverManager.java:154)
 at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
 at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
 ... 60 more
Caused by: com.informix.asf.IfxASFRemoteException: Kok.Hoe.Loh@128.230.11.83
 at com.informix.asf.Connection.recvConnectionResponse(Connection.java:688)
 at com.informix.asf.Connection.establishConnection(Connection.java:1613)
 at com.informix.asf.Connection.(Connection.java:347)
 at com.informix.jdbc.IfxSqliConnect.(IfxSqliConnect.java:1055)
 ... 69


Guess what is wrong with the code shown above? I was so surprise that I have miss type the hibernate.connection.username to hibernate.username and also hibernate.connection.password to hibernate.password.


Sunday, July 21, 2013

Beware of in web.xml

I have a Spring Security project sharing across two servers, one is a normal Tomcat, and another one with SSL configured. At one point, I have this code configured in web.xml:
    
        
            SpringSecurity3
            /*
        
        
            CONFIDENTIAL
        
    
The above code gives an instruction that only HTTPS is allowed to connect to the application. If I’m deploying the project into the Tomcat without SSL configure, I will hit the HTTP 404 error. This was quite annoying every time I deploy the code into 2 different servers where I need to comment and un-comment and then comment it back again and again. Until I found there is a solution to overcome this issue which is by configures this in Server’s web.xml. I am referring to the server project right inside the Eclipse workspace, not the physical Tomcat installation directory.

According to forum, if <transport-guarantee>CONFIDENTIAL</transport-guarantee> is omit, this will indicate that the application can be connect using HTTPS and HTTP. Otherwise Tomcat will automatically route to HTTPS.

Sunday, July 14, 2013

ClassCastException when subtype casting

    Object[] objects = new Object[10];
    String[] strings = (String[]) objects;
We all know that all objects in JAVA are drive from Object class. Does it true? If this statement is true then why the code shown above throw a ClassCastException in run-time? Now consider following code.
    String[] strings = new String[10];
    Object[] objects = (Object[]) strings;
     
    objects[0] = new String("simple Text");
    
    System.out.println(objects[0]);
The code compiles and execute successfully without error. And the content was print out at the end of the execution. Don't you think this is interesting? This code has prove that Object is holding a String in memory. I spent quite some time searching on this and I found this:
Java is a strongly typed language, and that means you can only cast an object to a type it extends from (either a superclass or an interface). – StackOverflow.com

Wednesday, July 3, 2013

What is EL Expression Unbalanced?

Here I got a web page developed using JSF 2.0. Anyhow I am not able to render the page correctly and following error shown on the page:

/thepage.xhtml @12,44 value="#{theBean.contactKey)" EL Expression Unbalanced: ... #{theBean.contactKey)

What is this error means? It took quite some time for me to understand this error message until I found out there is something not so right on the eval-expression construct, #{theBean.contactKey). There are 2 types of construct so far I read in the EL Expression book, either #{expr} or ${expr}. Thus there is no such thing #{expr).

Monday, July 1, 2013

Exclude test code being pack into WAR

Here is another stupid putting the test code right under the src directory. I am not sure what is the purpose of doing this since we know that test code should not be deploy into production server, thus I have to exclude it from the main code. I mean not to delete the test code but to exclude them from being package into WAR. This is how I do it:
    
        
        ....
    

SQLException: Field 'id' doesn't have a default

By using the code below in hibernate configuration file will automatically assign a value into ID column without assigning it manually.
    
        
            
        
        ...
        ...
    
Anyhow it does not work as expected and following rubbish being thrown.
    Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870)
     at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
     at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1169)
     at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:693)
     at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1404)
     at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1318)
     at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1303)
     at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:93)
     at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:56)
     ... 22 more
What is wrong with my code? According to my colleague, there is nothing wrong in my code, just the column ID in ORDERS table is not declare as auto increment. Thus by alter the table column to auto increment will solve the problem.

Thursday, June 27, 2013

Using anonymous array to initialize an array in JAVA

There was a mistake when I'm declaring an array of integer first, and attempt to initialize it later will get a compiler error. The following code is what I'm trying to describe.

int[] theArray;
theArray = {1, 2};

It has to be either do it in this way:

int[] theArray = {1, 2};  // (1)

or this way:

int[] theArray;
theArray = new int[] (1, 2);  // (2)

In (1), theArray is an initializer block used to create and initialize the elements. In (2), an anonymous array expression is used.

Sunday, June 23, 2013

How could I implement session timeout in Spring?

What a mess?!! I spend the whole morning to figure out how could I implement a session control over a user today. Being able to authenticate a user in a system is a good start, what if I want to enforce some session rules, say logout a user when the user idle for 5 minutes. I though Spring have some kind of special session management? Nope, no such thing. Just define it in Deployment Descriptor as shown in the following code will do.

   5

Take note that the number in session-timeout tag represent in minute.