Friday, August 23, 2013

How to configure log4j in CometD application


Logging is the most important part of an application because it helps developer a lot in getting the insight of any module or a block of code. Here we are going to use log4j for logging purpose. Log4j is a Reliable, Fast and Flexible Logging Framework (APIs) written in Java which is distributed under the Apache Software License. It is highly configurable through external configuration files at runtime. It views the logging process in terms of levels of priorities and offers mechanisms to direct logging information to a great variety of destinations, such as a database, file, console, UNIX Syslog etc.

It has 3 main components:

1.       loggers: These are responsible for capturing the logging information from specified package or file name as mentioned under “name” attribute. It also specifies the log level like info, debug etc and list of references of appenders that will display the logging informations.

2.       appenders: It is responsible for displaying the logging information at various destinations like console, log files etc. it also defines the pattern for showing logs under “layout” tags.

3.       layouts: It formats logging information according to our style and it is defined under appenders.

These tags are defined in log4j.xml file.

Steps to configure logs in cometd applications:

Step 1) Download jars: Following jars are needed for logging in cometd application like:

log4j-1.2.15.jar,
slf4j-api-1.6.4.jar,
slf4j-log4j12-1.6.4.jar

Step 2) Create log4j.xml: Create log4j.xml file that will have all logging informations like loggers, appenders, layouts etc as given below. Place this file in WEB-INF folder.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "dtd/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
 
  <appender name="aa" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="c:/JKLOG/aa-log.log" />
    <param name="MaxFileSize" value="5120KB" />
    <param name="MaxBackupIndex" value="30" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%x]  @ %C{1} : %M : %L - %m%n" />
    </layout>
  </appender>
 
  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%x]  @ %C{1}: %M : %L - %m%n"/>
    </layout>
  </appender>
 
 
  <root>
    <level value="warn"/>
    <appender-ref ref="aa" />
  </root>
 
   <logger name="com.test.ai.amap.gsontest.MyService">
        <level value="info" />
        <appender-ref ref="console" />
        <appender-ref ref="aa" /> 
       
  </logger>
 
  <logger name="org.cometd.server">
        <level value="all" />
        <appender-ref ref="console" />
        <appender-ref ref="aa" /> 
       
  </logger>
 
</log4j:configuration>

Step 3) Configure log4j.xml and test your applications: To configure and use log4j.xml file, we have to do two things.
  •  we have to create an instance of Logger class and that instance will be used to print out custom logs as private static final Logger _log = LogManager.getLogger(MyService.class);
  • We have to use “DOMConfigurator.configure("C:/workspace/POC/CometDIdea/WebContent/WEB-INF/log4j.xml");” to load the log4j.xml file and use it. Generally this is done in some servlet class in such a way that these code run only on time. I have done it in my service class.


package com.test.ai.amap.gsontest;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.cometd.bayeux.server.ConfigurableServerChannel;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.java.annotation.Configure;
import org.cometd.java.annotation.Listener;
import org.cometd.java.annotation.Service;
import org.cometd.server.authorizer.GrantAuthorizer;


@Service
public class MyService
{
      @org.cometd.java.annotation.Session
    private ServerSession _session;
      private static final Logger _log = LogManager.getLogger(MyService.class);
     
      public MyService(){          
            DOMConfigurator.configure("C:/workspace/POC/CometDIdea/WebContent/WEB-INF/log4j.xml");
      }
     
      @Configure("/service/*")
    public void configureExecuteCommand(ConfigurableServerChannel channel)
    {
      channel.addAuthorizer(GrantAuthorizer.GRANT_SUBSCRIBE_PUBLISH);
      channel.setPersistent(true);
    }
   
    @Listener("/service/foo")
    public void handleFooMessages(ServerSession remote, ServerMessage message)
    {
      System.out.println("---------------------Hello World---------------------------");
      _log.info("*************This is hello world logging from MyService.java***************");
      remote.deliver(_session, message.getChannel(),"I am Saying Hello World From Server", null);
    }
}


Note: It has been advised in CometD doc to use flag “logLevel” in web.xml so that it can control the log level. But, I found that its not working. The log level is controlled by <level value=" " /> tag under <logger> tag in log4j.xml file. If any one finds the way of using “logLevel”, please post your comment here. It will be helpful for us.

Friday, August 16, 2013

Network Reliability by CometD: Hello world in CometD

Friends! I am going to discuss just top of the CometD here.

While creating any web application for palm devices like mobile phone, tabs, ipad etc, the main villain is network failure. It always defeats our hero (web application) by kidnaping and destroying application data (data lost) on request – response chain. For smooth functioning of any web application there should be a guaranty that if data is sent from client, it will definitely reach to server and if server dispatches a response, it will certainly reach to corresponding client. To fulfill this requirement, we need a side hero i.e. a tool to establish Network reliability.

Here comes the role of Bayeux Protocol. It is used to establish the bidirectional interactions between web clients, for example using AJAX, and the web server. It provides several specifications to establish network reliability in Web Application. One of the implementation of these specifications is CometD by DOJO technology.

“CometD is a scalable web event routing bus that allows you to write low-latency, server-side, event-driven web applications. Typical examples of such applications are stock trading applications, web chat applications, online games, and monitoring consoles. CometD makes use of an Ajax push technology pattern known as Comet, but also uses emerging web standards such as WebSocket for low latency communication.is a scalable web event routing bus that allows you to write low-latency, server-side, event-driven web applications. Typical examples of such applications are stock trading applications, web chat applications, online games, and monitoring consoles.”

OHH!!!!! What a great….. English. Today, I came to know that even I can also write such English. Don’t worry, these are not my words. These are from CometD document.

I think, I have bored you a lot. So, before you start beating me, I should move on to the steps for configuring CometD and creating a Hellow world program.


Step 1) Download library and jar files: Download cometd-2.5.0-distribution.tar.gz from http://download.cometd.org/ and go to directory “cometd-2.5.0-distribution\cometd-2.5.0\cometd-demo\target”. Here, you will get cometd-demo-2.5.0.war. Use following command to unwar it: “jar –xvf cometd-demo-2.5.0.war”. Extract the following jar files from the newly created folder.



Along with above jar files, extract following javascript library files from the above unwar folder:



Step 2): Create a Dynamic Web Project in Eclipse.

Step 3): Copy the above jar files in lib folder and javascript library file in “resources” folder under WebContent.

Step 4): Create a web.xml file as given below:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <display-name>CometDPoc</display-name>
 
      <servlet>
        <servlet-name>cometd</servlet-name>
        <servlet-class>org.cometd.java.annotation.AnnotationCometdServlet</servlet-class>
        <async-supported>true</async-supported>        
        <init-param>
              <param-name>services</param-name>
            <param-value>com.test.ai.amap.gsontest.MyService</param-value>
          </init-param>   
       
        <load-on-startup>1</load-on-startup>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>cometd</servlet-name>
        <url-pattern>/cometd/*</url-pattern>
    </servlet-mapping>   
 
</web-app>

In this web.xml file AnnotationCometdServlet is the built-in servlet of CometD and it will receive all the request coming from client through cometD.

MyService is a java class that acts as the service class and it will be initialized by CometD container automatically and it is singleton. All the requests, coming to AnnotationCometdServlet, are forwarded to this service class.

Step 5): Create MyService.java service class:

package com.test.ai.amap.gsontest;

import org.cometd.bayeux.server.ConfigurableServerChannel;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.java.annotation.Configure;
import org.cometd.java.annotation.Listener;
import org.cometd.java.annotation.Service;
import org.cometd.server.authorizer.GrantAuthorizer;

@Service
public class MyService
{
      @org.cometd.java.annotation.Session
    private ServerSession _session;
     
      @Configure("/service/*")
    public void configureExecuteCommand(ConfigurableServerChannel channel)
    {
      channel.addAuthorizer(GrantAuthorizer.GRANT_SUBSCRIBE_PUBLISH);
      channel.setPersistent(true);
    }
   
    @Listener("/service/foo")
    public void handleFooMessages(ServerSession remote, ServerMessage message)
    {
      System.out.println("---------------------Hello World---------------------------");
      remote.deliver(_session, message.getChannel(),"I am Saying Hello World From Server", null);
    }
}

Function configureExecuteCommand() with annotation like “@Configure("/service/*")” makes all the service channel available for subscribing.

Function handleFooMessages() with annotation like “@Listener("/service/foo")” declares itself as the listener or subscriber for channel “/service/foo” and all the request published on this channel from client will come to this function.

Step 6): Create handshake function on client: Before starting communication with server through cometD, it is necessary to make a handshake of client with server where both detect each other’s compatibility. This is done by dojox.cometd.init() function of cometD as given in file CometDMessagingManager.js

Step 7) Create client side publisher of request on client: We have to create the client side publisher of request which publishes requests on service channel that are subscribed on java side by functions of service classes as done in echoRpc() function of user.js

Step 8) Create client side subscriber of response from server: We have to create the client side subscriber of the channel on which server sends the response. Actually server sends response on the save channel from which it has received the request. That means the client side subscriber should be created on same channel on which the client side publisher is created. It is done on echoRpc() function of user.js. In the attached application, the function echoRPCReturn() of user.js is the corresponding client side subscriber.

Step 9) Provide comet url: Provide the cometD url as http://localhost:8080/CometDIdea/cometd in the dojox.cometd.init() function in setUpMessaging() function of CometDMessagingManager.js file. This is the url where every request will be dispatched and they will be handled by AnnotationCometDServlet.java file as configured in web.xml file.

I have attached the complete application code. Please go through it for getting clear idea. Following url may be helpful.


I am not able to attach the code here. So, if anybody needs it, please email me on jksnu1@gmail.com or put a comment on this blog.

Sunday, August 11, 2013

ExtDirect: DirectGNGine Example


DirectJNgine (or DJN, for short) is a Java implementation of the Ext Direct API. This API allows applications using ExtJs to call Java methods from Javascript almost transparently, making things that used to be more or less cumbersome or time consuming much easier. We should follow following 8 steps to implement DJN:

1)      Download DJN Library Files: Download DirectJNGine.jar and add it to your classpath. If we want to use client side parameter checking debug-time support, we will need to add javascript files like djn-remote-call-support.js and ejn-assert.js.

2)      Configure DJN servlet in Web.xml:  Make entries for DJN servlet in WEB.xml as given below:

<!-- DirectJNgine servlet -->
<servlet>
                           <servlet-name>DjnServlet</servlet-name>
                           <servlet-class>com.softwarementors.extjs.djn.servlet.DirectJNgineServlet</servlet-class>
                           <init-param>
<param-name>providersUrl</param-name>
                                           <param-value>djn/directprovider</param-value>
                           </init-param>
<!-- more parameters... -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DjnServlet</servlet-name>
<url-pattern>/djn/directprovider/*</url-pattern>
</servlet-mapping>

3)      Create server side Action class and Direct Methods:  Create a class on server side that will have methods to be called directly on Client side as follows:

public class TestAction {
  @DirectMethod
  public String doEcho( String value ) {
                  return value;
  }
  @DirectMethod
  public double multiply( String num ) {
                  double num_ = Double.parseDouble(num);
                  return num_ * 8.0;
  }
}

Here, the class ‘TestAction’ is the Action class that will be exposed to client side and it must be defined in Web.xml file. The two methods in this class i.e. doEcho() and multiply() are the methods that can be directly called from client side.

4)      Tell DJN where to look for server methods: Here, the Action classes will be made exposed to client side by defining it in WEB.xml as follows:

<init-param>
                 <param-name>demo.classes</param-name>
                 <param-value>
com.softwarementors.extjs.djn.demo.TestAction                               
<!—More action classes will be defined here-->
                 </param-value>
            </init-param>

Remember, here demo is the api definition for ExtDirect examples, if we were configuring the test api, the parameter to configure would have been tests.classes. In later steps, we will learn how to define demo api definition in WEB.xml.

5)      Tell DJN where to look for Api definitions: In point (4), ‘demo’ is the Api definition for ExtDirect examples and in an application there may be more than one such api definition and DJN will find information about these api definition from WEB.xml where these are defined as follows:

<init-param>
                 <param-name>apis</param-name>
                 <param-value>demo</param-value>
                 <!—more api can be defined here-->
</init-param>

6)      Register exposed methods in Api.js: Generally we define the structure of our exposed server side methods in Api.js file. Normally, this file is generated automatically by DJN, so we don’t need to generate it manually. We should define our method in Api.js as follows:
                          
         Ext.app.REMOTING_API = {
               url : Ext.app.PROVIDER_BASE_URL,
               type : "remoting",
               actions : {
                      TestAction: [ {
                                      name : ‘doEcho’,
                                      len : 1,
                                      formHandler : false
                      } ]
                 }
         };

7)      Tell DJN where to find Api.js file: We tell DJN the path of Api.js file in WEB.xml as follows:

         <init-param>
              <param-name>demo.apiFile</param-name>
              <param-value>demo/Api.js</param-value>
         </init-param>

8)      Call exposed server side method directly from Javascript: We can now directly call the exposed method doEcho()  of class TestAction.java from Javascript directly as follows:

               TestAction.doEcho(text.getValue(), function(result, e)
               {
                     var  t = e.getTransaction();
                     out.append(String.format('<p><b>Successful call to {0}.{1} with ' + 'response:</b><xmp>{2}</xmp></p>',
                     t.action, t.method, Ext.encode(result)));
                     out.el.scrollTo('t', 100000, true);
               });

Note we are passing here a second parameter, a javascript function that will be called with the data returned by the server. We need to use a function to handle the result because remote calls are asynchronous, as it would not be a good idea to block the program waiting for the result. The function receives the call result in the result parameter, and additional data in the e event, including the transaction, which holds the invoked action and method names among other things. 


Get some idea about ExtDirect: A Magic