Hi All,

I have documented the project. You can have a look here[1]
<https://docs.google.com/document/d/1jWBTaSDnVMkY0vOqOnU2ZG7fK28QIyXPC23F-B19zJ0/edit>.
All suggestions are welcome.

[1]
https://docs.google.com/document/d/1jWBTaSDnVMkY0vOqOnU2ZG7fK28QIyXPC23F-B19zJ0/edit

Thanks.


On Tue, Aug 12, 2014 at 1:22 AM, Mohamed Nasmin <[email protected]>
wrote:

> Hi All,
>
> We had a demonstration session of the project on 4th August at WSO2. The
> jaggery and AS members reviewed the current implementation and suggested
> the following ideas.
>
> 01) Change the logger for this tomcat extension as tomcat uses
> org.apache.juli.logging.Log
>
> 02) Rather than using a lifecycle listener, create a servlet container
> initializer for registering context listener. Because we need to minimize
> the manual configuration in context.xml
>
> 03) Get the property values from the jaggery.properties file and set
> init-parameter in a loop
>
> 04) Add proper comments for the codes
>
> I updated the tomcat lifecycle listener with a serlvet container
> initializer. So that we do not have to configure the context.xml. Here[1] I
> updated the code for that. Also I did changes in the jaggery context
> listener[2] to run jaggery with tomcat8. Please have a look on this.
>
> [1]
> https://github.com/nasminspy/org.jaggeryjs.tomgery/tree/master/src/main/java/org/jaggeryjs/tomgery
> [2]
> https://github.com/nasminspy/org.jaggeryjs.apps/tree/master/src/main/java/org/jaggeryjs/apps
>
> Thanks.
>
>
> On Mon, Jul 21, 2014 at 7:04 PM, Mohamed Nasmin <[email protected]>
> wrote:
>
>> Hi All,
>>
>> We are developing the apache tomcat based runtime implementation for the
>> jaggery. This is to share status and get your all kinds of feedbacks. As a
>> workaround, a jaggery app was deployed on top of tomcat, subjecting to a
>> WEB-INF directory which contains jaggery core jars and web.xml.
>>
>> My task is to remove the WEB-INF directory in each context and put it to
>> a common directory to make it available for the execution of the jaggery
>> apps in the tomcat. Those jars and jaggery engines will be available when a
>> jaggery app deploys into the tomcat. To achieve this functionality I follow
>> these steps.
>>
>> 01) Catch a tomcat lifecycle event when a context gets deployed.
>> 02) Check whether the app in the tomcat webapps is jaggery app or not
>> before it gets started.
>> 03) Put the jars the tomcat that the jaggery apps can use.
>> 04) Keep the context parameters in a separate property file and make it
>> available for the app deployment.
>> 05) Register a jaggery context listener object for each jaggery app.
>>
>> You can have a look on the current implementation by following the below
>> instructions. Please note that these modules are tested on the apache
>> tomcat 7.0.54.
>>
>> 1) Copy this[1] jaggery folder which contains the jaggery engine, libs
>> and jaggery properties into your tomcat home.
>> 2) Add a tomcat lifecycle listener to context by adding the below line
>> into the context.xml. In our case the listener class name is
>> TomcatListener[2]
>>
>> <Listener className="org.jaggery.tomcat.listener.TomcatListener" />
>>
>> 3) Refer the jaggery core jars to the tomcat app in the
>> catalina.properties by replacing common loader.
>>
>>
>>
>> common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.base}/jaggery/lib,${catalina.base}/jaggery/lib/*.jar,${catalina.home}/jaggery/lib,${catalina.home}/jaggery/lib/*.jar
>>
>> 4) Put the demo jaggery applications[3] in the webapps folder of tomcat
>> 5) Start the tomcat and those apps can be accessed via below URLs
>>
>> http://localhost:8080/demo5/users/1
>> http://localhost:8080/demo3/index.jag
>> http://localhost:8080/demo1
>>
>> Note that current implementation was tested on the tomcat7 and I am
>> working on tomcat8 and tomcat6. Also i will do a study on some other
>> context parameters that we need to include. After that I will update the
>> latest jaggery context listener codes that we used here. I attached the
>> tomcat directory structure for the ease. All the feedbacks and advices are
>> welcome on this topic.
>>
>> [1] https://github.com/nasminspy/gitbox/raw/master/jaggery.zip
>> [2]
>> https://github.com/nasminspy/TomgeryRunner/blob/master/src/org/jaggery/tomcat/listener/TomcatListener.java
>> [3] https://github.com/nasminspy/gitbox/raw/master/samples.zip
>>
>> Thanks.
>>
>>
>> On Mon, Jul 21, 2014 at 1:06 PM, Mohamed Nasmin <[email protected]>
>> wrote:
>>
>>> Sure. I will send an update on the progress soon.
>>>
>>>
>>> On Mon, Jul 21, 2014 at 12:46 PM, Sagara Gunathunga <[email protected]>
>>> wrote:
>>>
>>>>
>>>> Hi Nasmin,
>>>>
>>>> Can you please send a mail to architecture@ list about your progress,
>>>> current status, architectural changes etc.
>>>>
>>>> Thanks !
>>>>
>>>> On Wed, Jul 9, 2014 at 5:59 PM, Chamil Jeewantha <[email protected]>
>>>> wrote:
>>>>
>>>>> Hi All,
>>>>>
>>>>> I have check the source code with Nasmin and found,
>>>>>
>>>>> the JaggeryAsyncServlet is already registered before it does
>>>>> programatically because JaggeryAsyncServlet class is automatically added 
>>>>> to
>>>>> all the Webapp Contexts because of the @WebServlet annotation.
>>>>>
>>>>>
>>>>> @WebServlet(name = "JaggeryAsyncServlet", urlPatterns = "/*",
>>>>> asyncSupported = true)
>>>>>
>>>>> Since this JaggeryAsyncServlet is added selectively (only for the
>>>>> Jaggery apps), The @WebServlet should be removed.
>>>>>
>>>>> Regards,
>>>>>  Chamil
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Tue, Jul 1, 2014 at 12:10 AM, Mohamed Nasmin <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> After some reading I found the above null pointer comes when we
>>>>>> adding the context listener BEFORE_START_EVENT occurs. So I changed the
>>>>>> event to STARTING. Now without any error the jaggery context listener 
>>>>>> added
>>>>>> to the standard context.
>>>>>>
>>>>>> But when access the sample tomgery application through URL I got this
>>>>>> error. When I debug this[1] I found appConfigs is null. But could not 
>>>>>> find
>>>>>> how it happened. Thanks in advance.
>>>>>>
>>>>>> *Code : *
>>>>>>
>>>>>> protected void service(HttpServletRequest request,
>>>>>>                            HttpServletResponse response) throws
>>>>>> ServletException, IOException {
>>>>>>         JaggeryAppConfigs appConfigs =
>>>>>> JaggeryAppConfigs.getInstance(request.getServletContext());
>>>>>>         request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED",
>>>>>> true);
>>>>>>         AsyncContext asyncCtx = request.startAsync();
>>>>>>         asyncCtx.addListener(new JaggeryAsyncListener());
>>>>>>         asyncCtx.setTimeout(appConfigs.getServletTimeout());
>>>>>>         appConfigs.getServletExecutor().execute(new
>>>>>> JaggeryAsyncRequestProcessor(asyncCtx));
>>>>>>     }
>>>>>>
>>>>>> *Exception :*
>>>>>>
>>>>>> java.lang.NullPointerException
>>>>>>  
>>>>>> org.jaggeryjs.apps.JaggeryAsyncServlet.service(JaggeryAsyncServlet.java:23)
>>>>>>  javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
>>>>>>  org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>>>>>>
>>>>>> [1]
>>>>>> https://github.com/ruchiraw/jaggery/blob/master/components/jaggery-core/org.jaggeryjs.apps/src/main/java/org/jaggeryjs/apps/JaggeryAsyncServlet.java
>>>>>>
>>>>>>
>>>>>> On Sun, Jun 22, 2014 at 5:54 AM, Chamil Jeewantha <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Nasmin,
>>>>>>>
>>>>>>> the Null Pointer Exception (NPE) comes from the line
>>>>>>>
>>>>>>> registration.setAsyncSupported(true);
>>>>>>>
>>>>>>> Which means "registration" object is null. The responsible line of
>>>>>>> assigning this variable is the line 25.
>>>>>>>
>>>>>>> ServletRegistration.Dynamic registration = servletContext.addServlet(
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                 JaggeryAsyncServlet.NAME, JaggeryAsyncServlet.class);
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> servletContext.addServlet javadoc[1] says,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> a ServletRegistration object that may be used to further configure the 
>>>>>>> registered servlet, or *null** if this ServletContext already contains 
>>>>>>> a complete ServletRegistration for the given **servletName*
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> For this case you can start debug by two points.
>>>>>>>
>>>>>>> 1. debug JaggeryContextListener
>>>>>>> 2. Debug with tomcat source - servletContext.addServlet method to see 
>>>>>>> why it returns null here.
>>>>>>>
>>>>>>>
>>>>>>> [1] 
>>>>>>> http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#addServlet(java.lang.String,
>>>>>>>  java.lang.Class)
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Sat, Jun 21, 2014 at 10:08 PM, Mohamed Nasmin <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> @Ruchira
>>>>>>>> I will debug the jars that we use in the tomgery app deployment and
>>>>>>>> update with the results.
>>>>>>>>
>>>>>>>> @Dilshan
>>>>>>>> I am using that JaggeryContextListener in a jar which is created by
>>>>>>>> Ruchira. You can find the source code of that jar here[1].
>>>>>>>>
>>>>>>>> @Dakshika
>>>>>>>> With the integration with JSR-223, Jaggery will use Nashorn from
>>>>>>>> JDK8 onwards and will fallback to JDK's embeded Rhino version with 
>>>>>>>> JDK7 or
>>>>>>>> below. With the above Jaggery core minimisations, a Jaggery app can be 
>>>>>>>> even
>>>>>>>> deployed on top of tomcat, subjecting to a WEB-INF directory which 
>>>>>>>> contains
>>>>>>>> jaggery core jars and web.xml. For more details please refer this 
>>>>>>>> link[2].
>>>>>>>>
>>>>>>>> [1]
>>>>>>>> https://github.com/ruchiraw/jaggery/blob/master/components/jaggery-core/org.jaggeryjs.apps/src/main/java/org/jaggeryjs/apps/JaggeryContextListener.java
>>>>>>>> [2]
>>>>>>>> http://osdir.com/ml/carbon-wso2-architecture/2014-06/msg00000.html
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sat, Jun 21, 2014 at 9:46 PM, Dilshan Edirisuriya <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> Whats there at line 27 of JaggeryContextListener.java? Where can
>>>>>>>>> we find the source for this?
>>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>>
>>>>>>>>> Dilshan
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Sat, Jun 21, 2014 at 1:31 PM, Mohamed Nasmin <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>>  According to our earlier conversation I am following the below
>>>>>>>>>> progression to accomplish the project. Sorry for the lengthy email.
>>>>>>>>>>
>>>>>>>>>> *Task1. Check whether the app in the tomcat webapps is jaggery
>>>>>>>>>> app or not before it gets deployed/initialized*
>>>>>>>>>>
>>>>>>>>>> I trigger the BEFORE_START_EVENT by configuring the tomcat
>>>>>>>>>> lifecycle listener with context.xml in the tomcat. The context can 
>>>>>>>>>> listen
>>>>>>>>>> to the lifecycle listener by putting jar inside lib folder of 
>>>>>>>>>> tomcat. That
>>>>>>>>>> jar should contain the tomcat listener. Also we need to define that 
>>>>>>>>>> class
>>>>>>>>>> in the context.xml like below (For more details please refer this 
>>>>>>>>>> mail with
>>>>>>>>>> subject Tomcat Lifecycle listener how to.).
>>>>>>>>>>
>>>>>>>>>> <Listener className="org.jaggery.tomcat.listener.TomcatListener"
>>>>>>>>>> />
>>>>>>>>>>
>>>>>>>>>> When an application is started to deploy BEFORE_START_EVENT will
>>>>>>>>>> be occurred. we check that event get the standard context of that 
>>>>>>>>>> event. To
>>>>>>>>>> find out whether it is a jaggery context or not we identify the
>>>>>>>>>> jaggery.conf in that app folder.
>>>>>>>>>>
>>>>>>>>>> Code :
>>>>>>>>>>
>>>>>>>>>> public void lifecycleEvent(LifecycleEvent event) {
>>>>>>>>>>
>>>>>>>>>>         String type = event.getType();
>>>>>>>>>>         if (Lifecycle.BEFORE_START_EVENT.equals(type)) {
>>>>>>>>>>             LOGGER.log(Level.INFO, "BEFORE START EVENT
>>>>>>>>>> triggered.");
>>>>>>>>>>             Lifecycle source = event.getLifecycle();
>>>>>>>>>>
>>>>>>>>>>             if (source instanceof StandardContext) {
>>>>>>>>>>
>>>>>>>>>>                 StandardContext standardContext =
>>>>>>>>>> (StandardContext) source;
>>>>>>>>>>                 boolean exists = isJaggeryApp(standardContext);
>>>>>>>>>>
>>>>>>>>>>                 if (!exists) {
>>>>>>>>>>                     System.out.println("This is not a Jaggery
>>>>>>>>>> app");
>>>>>>>>>>                 } else {
>>>>>>>>>>                     System.out.println("This is a Jaggery app");
>>>>>>>>>>                 }
>>>>>>>>>>             }
>>>>>>>>>>         }
>>>>>>>>>>     }
>>>>>>>>>>
>>>>>>>>>>  public boolean isJaggeryApp(StandardContext standardContext) {
>>>>>>>>>>
>>>>>>>>>>         String contextPath = standardContext.getPath();
>>>>>>>>>>         String catalinaPath = System.getProperty("catalina.base");
>>>>>>>>>>
>>>>>>>>>>         try{
>>>>>>>>>>         File file = new File(catalinaPath + File.separator +
>>>>>>>>>> "webapps" + contextPath + File.separator + "jaggery.conf");
>>>>>>>>>>         boolean exists = file.exists();
>>>>>>>>>>         }
>>>>>>>>>>         catch (Exception e){
>>>>>>>>>>             e.printStackTrace();
>>>>>>>>>>         }
>>>>>>>>>>
>>>>>>>>>>         if (!exists) {
>>>>>>>>>>             return false;
>>>>>>>>>>         } else {
>>>>>>>>>>             return true;
>>>>>>>>>>         }
>>>>>>>>>>
>>>>>>>>>>     }
>>>>>>>>>>
>>>>>>>>>> Output:
>>>>>>>>>>
>>>>>>>>>> INFO: Deploying web application directory
>>>>>>>>>> /home/nasmin/tomcat/apache-tomcat-7.0.54/webapps/demo3
>>>>>>>>>> Jun 20, 2014 10:25:40 PM
>>>>>>>>>> org.jaggery.tomcat.listener.TomcatListener lifecycleEvent
>>>>>>>>>> INFO: BEFORE START EVENT triggered.
>>>>>>>>>> This is a Jaggery app
>>>>>>>>>>
>>>>>>>>>> *Task2. How to put the jars in the tomcat that apps can see*
>>>>>>>>>>
>>>>>>>>>> After finding the jaggery app in the tomcat we need to assign
>>>>>>>>>> some jar which will be required to get new jaggery engine. So we can 
>>>>>>>>>> put
>>>>>>>>>> the in a directory in the tomcat and we need to mention that in the
>>>>>>>>>> catalina.properties like below.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.base}/jaggery/lib,${catalina.base}/jaggery/lib/*.jar,${catalina.home}/jaggery/lib,${catalina.home}/jaggery/lib/*.jar
>>>>>>>>>>
>>>>>>>>>> *Task3. Register a jaggery servlet listener if it is a jaggery
>>>>>>>>>> app *
>>>>>>>>>>
>>>>>>>>>> Afterwards we need to register our jaggery servlet listener to
>>>>>>>>>> the jaggery app. I did by adding application listener to the jaggery
>>>>>>>>>> standard context and I added application paramaeter which we had in 
>>>>>>>>>> the
>>>>>>>>>> web.xml. Here I got an exception like below. Please advice on this.
>>>>>>>>>>
>>>>>>>>>> Code:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> standardContext.addApplicationListener("org.jaggeryjs.apps.JaggeryContextListener");
>>>>>>>>>>
>>>>>>>>>> ApplicationParameter applicationParameter = new
>>>>>>>>>> ApplicationParameter();
>>>>>>>>>> applicationParameter.setName("jaggery.initializer");
>>>>>>>>>> applicationParameter.setValue("server://engines/index.js");
>>>>>>>>>> standardContext.addApplicationParameter(applicationParameter);
>>>>>>>>>>
>>>>>>>>>> ApplicationParameter applicationParameter1 = new
>>>>>>>>>> ApplicationParameter();
>>>>>>>>>> applicationParameter1.setName("jaggery.development");
>>>>>>>>>> applicationParameter1.setValue("true");
>>>>>>>>>> standardContext.addApplicationParameter(applicationParameter1);
>>>>>>>>>>
>>>>>>>>>> ApplicationParameter applicationParameter2 = new
>>>>>>>>>> ApplicationParameter();
>>>>>>>>>> applicationParameter2.setName("jaggery.engine.pool.max.active");
>>>>>>>>>> applicationParameter2.setValue("5000");
>>>>>>>>>> standardContext.addApplicationParameter(applicationParameter2);
>>>>>>>>>>
>>>>>>>>>> ApplicationParameter applicationParameter3 = new
>>>>>>>>>> ApplicationParameter();
>>>>>>>>>> applicationParameter3.setName("jaggery.executor.pool.max");
>>>>>>>>>> applicationParameter3.setValue("5000");
>>>>>>>>>> standardContext.addApplicationParameter(applicationParameter3);
>>>>>>>>>>
>>>>>>>>>> Output:
>>>>>>>>>>
>>>>>>>>>> INFO: Deploying web application directory
>>>>>>>>>> /home/nasmin/tomcat/apache-tomcat-7.0.54/webapps/demo5
>>>>>>>>>> Jun 20, 2014 10:25:39 PM
>>>>>>>>>> org.jaggery.tomcat.listener.TomcatListener lifecycleEvent
>>>>>>>>>> INFO: BEFORE START EVENT triggered.
>>>>>>>>>> This is a Jaggery app
>>>>>>>>>> Jun 20, 2014 10:25:40 PM org.apache.catalina.core.StandardContext
>>>>>>>>>> listenerStart
>>>>>>>>>> SEVERE: Exception sending context initialized event to listener
>>>>>>>>>> instance of class org.jaggeryjs.apps.JaggeryContextListener
>>>>>>>>>> java.lang.NullPointerException
>>>>>>>>>>     at
>>>>>>>>>> org.jaggeryjs.apps.JaggeryContextListener.contextInitialized(JaggeryContextListener.java:27)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1247)
>>>>>>>>>>     at
>>>>>>>>>> org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1898)
>>>>>>>>>>     at
>>>>>>>>>> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
>>>>>>>>>>     at java.util.concurrent.FutureTask.run(FutureTask.java:262)
>>>>>>>>>>     at
>>>>>>>>>> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
>>>>>>>>>>     at
>>>>>>>>>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
>>>>>>>>>>     at java.lang.Thread.run(Thread.java:744)
>>>>>>>>>>
>>>>>>>>>> Jun 20, 2014 10:25:40 PM org.apache.catalina.core.StandardContext
>>>>>>>>>> startInternal
>>>>>>>>>> SEVERE: Error listenerStart
>>>>>>>>>>
>>>>>>>>>> I attached the tomcat directory structure for the jaggery app
>>>>>>>>>> with this email. Also we have a remaining task that we need put 
>>>>>>>>>> context
>>>>>>>>>> parameters in a separate property file and make it available for the 
>>>>>>>>>> app
>>>>>>>>>> deployment. Here I hard coded those parameters. Please advice on this
>>>>>>>>>> issue.
>>>>>>>>>>
>>>>>>>>>> Thanks in advance.
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> Dev mailing list
>>>>>>>>>> [email protected]
>>>>>>>>>> http://wso2.org/cgi-bin/mailman/listinfo/dev
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Dilshan Edirisuriya
>>>>>>>>> Senior Software Engineer - WSO2
>>>>>>>>> Mob: + 94 777878905
>>>>>>>>> http://wso2.com/
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> Dev mailing list
>>>>>>>> [email protected]
>>>>>>>> http://wso2.org/cgi-bin/mailman/listinfo/dev
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> K.D. Chamil Jeewantha
>>>>>>> Associate Technical Lead
>>>>>>> WSO2, Inc.;  http://wso2.com
>>>>>>> Mobile: +94716813892
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> K.D. Chamil Jeewantha
>>>>> Associate Technical Lead
>>>>> WSO2, Inc.;  http://wso2.com
>>>>> Mobile: +94716813892
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Dev mailing list
>>>>> [email protected]
>>>>> http://wso2.org/cgi-bin/mailman/listinfo/dev
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Sagara Gunathunga
>>>>
>>>> Senior Technical Lead; WSO2, Inc.;  http://wso2.com
>>>> V.P Apache Web Services;    http://ws.apache.org/
>>>> Linkedin; http://www.linkedin.com/in/ssagara
>>>> Blog ;  http://ssagara.blogspot.com
>>>>
>>>>
>>>
>>
>
_______________________________________________
Dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/dev

Reply via email to