Monday, August 26, 2013

Launching WebSphere Liberty Profile from MAVEN

Good day ^o^ Finally I have successfully launch WebSphere Liberty Profile from MAVEN. But only in Linux, not in Windows. I wasn't really sure what is happening on Windows? Because when I launch the server directly from command prompt as shown below will immediately return an error.

server.bat start MyServer

Since even command prompt has failed, it will be the same in MAVEN. Anyhow that only happened on Windows. Only Windows will always cause trouble to me! Now my objective is to configuration MAVEN goal like this > clean install liberty:start-server. To achieve this, some workaround is needed.

1. First thing to do is to declare a repository for Liberty Profile in pom.xml as shown below:
 
  
   WASdev
   WASdev Repository
   http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository/
   default
   
    false
   
   
    true
   
  
 
2. Then declare a start-server goal as shown below:
  
   com.ibm.websphere.wlp.maven.plugins
   liberty-maven-plugin
   1.0
   
      /home/kokhoe/tool/wlp
      MyInstance
   
   
      
         start-server
         pre-integration-test
         
            start-server
         
         
            200
            /home/kokhoe/tool/wlp/usr/servers/MyInstance/server.xml
         
      
   
   ...
   ...
3. Open the server.xml which I have specified during the step 2 of the MAVEN configuration, add/replace the following code.

*NOTE: The default value of location attribute is without the full path and version number.

To determine the location attribute, this is how I do it. At the beginning of MAVEN configuration, I have this:
    org.huahsin
    WebProject
    0.0.1-SNAPSHOT
    war
That is for MAVEN allocate my web application in repository. With this information, I know that during the install stage life cycle, my application will be installed into following location:

/home/kokhoe/.m2/repository/org/huahsin/WebProject/0.0.1-SNAPSHOT/

By now when MAVEN build is trigger, it will automatically package and deploy, and the server is ready to listening incoming request.

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.

Sunday, August 18, 2013

My passion in game development is never lose

I have spend most of my time on OpenGL and Win32 programming since 2002 after finish my C programming lesson in my college. OpenGL and Win32 isn't in my course syllabus but game programming that causes me to pick up for myself. To make a game I must have a game engine up, without game engine it is real hard to roll out a game. In order to build a game engine, the primary element I must know of is graphic programming. I haven't go into other elements like audio, multiplayer, game design, story board, physic and mathematics.

Due to my work load at day job, I really had no time for this. There are so many thing in game programming I got to learn, thus my progress was really slow. Especially when my professional skill wasn't in game development. I understand that building a game engine from ground up is really time consuming. I need to utilize my time effectively. During the long holiday on last week, I found Unity3d. It is a game engine, easy to use (comparing to my previous experience on Vicious Engine), they use MonoDevelop as the engine scripting tool, support JavaScript and C#. I have spend some days (less than a week) to play around with it, I have my game completed, which consist of a spaceship shooting the asteroid, with sound, artwork, physic, and scoring system up and running fine.

Not bad. This engine can safe lots of my time. My passion in game development is never lose. Below is a short video that could motivate me to go stronger in game development.

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.