Sebastien Dionne

  • Increase font size
  • Default font size
  • Decrease font size
Welcome to the Frontpage

Enhance your javadoc with ULMGraph

E-mail Print PDF

We can't live without Javadoc, but even if it useful, it's not complete. One missing thing is UML within the Javadoc.

To add UML to your Javadoc, is quite simple. You need to add Graphviz into your maven build.

First you need to download and install Graphviz. Go there Graphviz

After that you should add the variable GRAPHVIZ_HOME (that point to the installation folder) into your system.

The last step is to add the plugin into your pom.

Add the lines in bold.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <version>2.6.1</version>
  <configuration>
    <links>
      <link>http://java.sun.com/javase/6/docs/api/</link>
    </links>
    <detectOfflineLinks />
    <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
    <!--
      use this line or use the variable GRAPHVIZ_HOME
      <docletPath>/path/to/UmlGraph.jar</docletPath>
    -->
    <docletArtifact>
      <groupId>org.umlgraph</groupId>
      <artifactId>doclet</artifactId>
      <version>5.1</version>
    </docletArtifact>

    <additionalparam>-operations</additionalparam>
    <additionalparam>-qualify</additionalparam>
    <additionalparam>-types</additionalparam>
    <additionalparam>-visibility</additionalparam>
    <additionalparam>-collpackages</additionalparam>
    <show>private</show>
  </configuration>
</plugin> 

With that you will have nice UML into your javadoc. I hope that help.


 

Extends javadoc with custom tag

E-mail Print PDF

I would like to show you how you could extend your javadoc to include samples directly into the javadoc without extra work.

What I don't like about javadoc is the lack of code sample. Something is can be hard to find the starting point of a new framework.

Let's show a example, it will be easier to understand, and so simple.


 /** 
 *
 * This in a javadoc with a custom tag @example.
 *
 * @author Sebastien Dionne
 *
 * @example.
 * <pre>
 * 
 * SSDPControler controler = new SSDPControler();
 * 
 * // sends messages each 30 seconds.
 * controler.getPeriodicMessageSender().setDelay(30000);
 *
 * controler.setPeriodicMessageSender(new SSDPPeriodicMessageSender(null) {
 *     @Override
 *     public List<String> returnHellos() {
 *         List<String> list = new ArrayList<String>();
 *
 *         list.add("hello1");
 *         list.add("hello2");
 *
 *         return list;
 *     }
 * });
 * controler.start();
 * </pre>
 */

In this example, we used a custom tag @example. The result will look like this.


...
public class SSDPControler
extends Object
implements ISSDPControler
...
This in a javadoc with a custom tag @example.

Example :

    SSDPControler controler = new SSDPControler();
 
    // sends messages each 30 seconds.
    controler.getPeriodicMessageSender().setDelay(30000);
 
    controler.setPeriodicMessageSender(new SSDPPeriodicMessageSender(null) {
       @Override
       public List<String> returnHellos() {
           List<String> list = new ArrayList<String>();
  
           list.add("hello1");
           list.add("hello2");
  
           return list;
       }
   });
   controler.start();

There is a thing that you need to know to avoid surprises :

Javadoc tool will cut the custom tag as soon as it detect another annotation, so don't forget to convert to HTML code like
@ : become : "&"#64;


To acheive that you need to add little config into your pom. Add the lines in bold.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.6.1</version>
    <configuration>
          <links>
            <link>http://java.sun.com/javase/6/docs/api/</link>
          </links>
          <detectOfflineLinks/> 
          
          <tags>
            <tag>
              <name>example.</name>
              <placement>aoptcmf</placement>
              <head>Example :</head>
            </tag>
          </tags>
          
      </configuration>
</plugin>

Last Updated ( Friday, 20 November 2009 18:33 )
 

GWS Deployer 1.9.17 : Reloaded : New Features Part 3 : PHP Support

E-mail Print PDF

In a previous post : PART2 I describe how to run JSP over Grizzly. Now I'll show you how to run PHP over Grizzly.

here a sample web.xml file for PHP support. (I'm using Quercus, but you could use native PHP too).

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>
  <description>Caucho Technology's PHP Implementation</description>

  <servlet>
    <servlet-name>Quercus Servlet</servlet-name>
    <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Quercus Servlet</servlet-name>
    <url-pattern>*.php</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.php</welcome-file>
  </welcome-file-list>

</web-app>


The last step is to put the required jars into the classpath.
You could put them in the command line with -cp or --classpath or you could use Deployer's param :

--libraryPath=[path]

Example : --libraryPath=/libs:/common_libs

With that you can have PHP support only if you want.

Follow us on Twitter

Last Updated ( Friday, 11 September 2009 19:03 )
 

GWS Deployer 1.9.17 : Reloaded : New Features Part 2 : JSP Support

E-mail Print PDF

Grizzly Deployer got lot of activity recently over mailing list, so I took the time to give you a new feature
that been added to the release 1.9.17. The Autodeploy command.

You should see that option like a default web.xml config that will be append to all your webapps
that you will deploy. You can activate this feature by adding this param to the command line :

java -jar grizzly-http-servlet-deployer-1.9.18-SNAPSHOT.jar --autodeploy=[path]

Example : --autodeploy=/folder/autodeploy

You need to create one of more web.xml files that you will put in that folder. Each web.xml config will be append to all your webapps.

here a sample for JSP support using Jasper.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
      <param-name>xpoweredBy</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
  </servlet>
      
  <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
  </servlet-mapping>
  
</web-app>


The last step is to put the required jars into the classpath.
You could put them in the command line with -cp or --classpath or you could use Deployer's param :

--libraryPath=[path]
Example : --libraryPath=/libs:/common_libs

With that you can have JSP support only if you want.

Follow us on Twitter

Last Updated ( Friday, 11 September 2009 09:10 )
 

GWS Deployer 1.9.17 : Reloaded : New Features Part 1

E-mail Print PDF

It has been a while since my last post, but I'm back :)

I worked hard on new features that will bring GWS Deployer to another level. You can check the features that were there before 1.9.17 in my previous post here

It will be easier to list the new features by looking at the command line parameters.

Usage: com.sun.grizzly.http.servlet.deployer.GrizzlyWebServerDeployer

--application=[path]* Application(s) path(s).
--port=[port] Runs Servlet on the specified port.
--context=[context] Force the context for a servlet.
--dontstart=[true/false] Won't start the server.
--libraryPath=[path] Add a libraries folder to the classpath.
--autodeploy=[path] AutoDeploy to each applications
--cometEnabled Starts the AsyncFilter for Comet
--forceWar Force war's deployment over a expanded folder.
--ajpEnabled Enable mod_jk.
--help Show this help message.
--longhelp Show detailled help message.

* are mandatory

The first new parameter is : --longhelp

This parameter will give a better explanation and default values.
 
java -jar http-servlet-deployer-1.9.17-SNAPSHOT.jar --longhelp


Usage: com.sun.grizzly.http.servlet.deployer.GrizzlyWebServerDeployer

-a, --application=[path]* Application(s) path(s).

Application(s) deployed can be :
Servlet(s), war(s) and expanded war folder(s).
To deploy multiple applications
use File.pathSeparator

Example : -a /app.war:/servlet/web.xml:/warfolder/


-p, --port=[port] Runs Servlet on the specified port.
Default: 8080

-c, --context=[context] Force the context for a servlet.
Only valid for servlet deployed using
-a [path]/[filename].xml

--dontstart=[true/false] Won't start the server.
You will need to call the start method.
Useful for Unit testing.
Default : false

--libraryPath=[path] Add a libraries folder to the classpath.
You can append multiple folders using
File.pathSeparator

Example : --libraryPath=/libs:/common_libs

--autodeploy=[path] AutoDeploy to each applications.
You could add JSP support.
Just add a web.xml that contains Jasper

Example : --autodeploy=/autodeploy

--cometEnabled=[true/false] Starts the AsyncFilter for Comet.
You need to active this for comet applications.
Default : false

--forceWar=[true/false] Force war's deployment over a expanded folder.
Will deploy the war instead of the folder.
Default : false

--ajpEnabled=[true/false] Enable mod_jk.
Default : false

Default values will be applied if invalid values are passed.

* are mandatory

Follow us on Twitter
Last Updated ( Thursday, 06 August 2009 09:24 )
 

New Grizzly enhancement : Servlet AutoDeployer

E-mail Print PDF

We got something really cool for Grizzly. It's a Servlet AutoDeployer for GrizzlyWebServer.

Now that it said.. let's talk more about that.

When you have servlets, you will need a AppServer or a WebServer to deploy your applications. Nothing new there.. it's a been like that for years. Mostly you had to create a web.xml, put that in a war and deploy it.

There are others alternatives, like using GrizzlyWebServer, but you will have to put your web.xml into code.

GrizzlyWebServer ws = new GrizzlyWebServer(80);

try {
ServletAdapter sa = new ServletAdapter();
sa.setContextPath("/");

// need to load JspRuntimeContext
Class.forName("org.apache.jasper.compiler.JspRuntimeContext");

Servlet servlet = (Servlet)ClassLoaderUtil.load("ca.sebastiendionne.welcome_jsp");
sa.setServletInstance(servlet);

ws.addGrizzlyAdapter(sa, new String[]{});
ws.start();
} catch (Exception e){
s_logger.error("Error Launching GrizzlyWebServer",e);
}

What's wrong with that ?

In my point of view.. it's not efficient. I don't want to use a WebServer to deploy a simple servlet and I don't want code what I could simply extract from a config file.

That why a servlet autodeployer could be useful. Yes a WebServer or AppServer do that already, but like I said.. you can skip it and go for a smaller and faster solution.

The GrizzlyServletDeployer (or the super fast and super easy thing for GrizzlyWebServer) will do everything for you.

In one simple command line you can deploy multiple applications.

Let's take a look at the command line first.

java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar [options]

where options are :

-p : the port [default 8080]
-a : applications to deploy (everything is done from that)

You can deploy many things from the option "-a" (servlets, war, multiple wars, expanded wars). Let's decribe what can be done.

Syntax examples :

# 1 : Deploy a war

java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar -a c:/temp/hudson.war

That will deploy the war file. The same way a WebServer will deploy it. The web.xml will be read and the servlets will be deployed.

The context will be the war file. In this example : http://localhost:8080/hudson/

#2 - Deploy a expanded war.

java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar -a c:/temp/hudson

Your application could be a expanded war, or have the same hierarchy.

That will give the same result as #1


#3 Deploy servlets


java -classpath myservlet.jar;.;grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar com.sun.grizzly.http.servlet.deployer.GrizzlyWebServerDeployer -a web.xml
You can skip the step to create a war file if you want. Simply declare a web.xml and put the jars into the classpath (in this case the servlet is in myservlet.jar)

The context will be the default "/"

http://localhost:8080/


#4 - Deploy multiples war in the same time.

This one is more advanced. It will deploy all the war files or expanded wars that are in a root folder.

java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar -a /MultipleWarFolder

(yes it's the same syntax as #2)

Example :

Here what the folders will look like


...../MultipleWarFolder/
/freemarker
/WEB-INF
/classes/
/lib/
/templates/
/web.xml
hudson.war
struts2-showcase-2.0.12.war
cometd-demo.war
sebastiendionne-is-the-man.war

The folder /MultipleWarFolder contains 4 war files and 1 expanded folder.

Serlvet-Deployer will check all the folders in the root (/MultipleWarFolder) and check if it can apply #1 or #2.

If it find one that contains /WEB-INF/web.xml it will consider it as #2 (expanded war) and if it find a .war it will do #1 (war file).

The context for each application will be the folder name (freemarker) or the war file.


If you want to can use it in a testcase easily.

GrizzlyWebServerDeployer gws = new GrizzlyWebServerDeployer();

try {

args = new String[]{"-a","./web.xml"};

// ready to launch
gws.init(args);
gws.launch();

... launch your tests...

} catch (Exception e){
e.printStackTrace();
}


I think when you will start using that, you will love it :)

GrizzlyWebServer is really powerful and so small. It's a Asynchronous IO server that support multiples protocols : HTTP(s), Comet, PHP, JSP, Freemarker, AJP protocol (mod_jk) and more check (https://grizzly.dev.java.net/).
Last Updated ( Wednesday, 01 April 2009 20:43 )
 

Read web.xml with one line of code Part 2

E-mail Print PDF

I did a <a href="http://weblogs.java.net/blog/survivant/archive/2008/12/read_webxml_wit.html">previous post</a> about how to do it with XMLBean or JABX, but it was more an example how to do it.  This time is the real deal. 

I used JABX to generate the java classes from the schemas and use that to parse the web.xml.

The result is a simple class : WebAppLoader  that will load the web.xml.

Here a example :

WebappLoader webappLoader = new WebappLoader();
WebApp webapp = webappLoader.load("/web-2.2.xml");


The object WebApp contains all the infos extracted from the web.xml.  The representation is based on webapp 3.0. 

you can get the source code from my repository : <a href="http://kenai.com/projects/sebastiendionne/sources/repository/show/dtd-schemas-generator">http://kenai.com/projects/sebastiendionne/sources/repository/show/dtd-schemas-generator</a>

 

How to configure proxy on Glassfish v3

E-mail Print PDF

If you are behind a proxy maybe you will want to set the proxy in Glassfish. There are few different ways to do that. #1 - You could use the admin web page. You can add the proxy settings : host and port with the admin. Into the admin web page, go to the Application Server at your left. After that on your right select : JVM Settings / JVM Options. Just add theses settings : http.proxyHost=myproxy.mydomain http.proxyPort=myproxy.port Glassfish_proxy.png
Click here to enlarge
#2 - You could use the command line Go into your Glassfish installation /bin and enter theses commands : asadmin create-jvm-options "-Dhttp.proxyHost=myproxy.mydomain" asadmin create-jvm-options "-Dhttp.proxyPort=myproxy.port" #3 - The last option is to edit manually domain.xml You add the settings in the "<java-config>" element. <java-config ...> <jvm-options>-Dhttp.proxyHost=myproxy.mydomain</jvm-options> <jvm-options>-Dhttp.proxyPort=myproxy.port</jvm-options> ...
 

JAXB : web.xml : dtd and xsd classes generator

E-mail Print PDF

I created a little demo to show how easy it can be to create a kit of classes from DTD and XSD using Maven and JAXB.

To generate from XSD schemas

In your pom.xml, you will have to add this.

<dependencies>
    <dependency>
		  <groupId>com.sun.xml.bind</groupId>
		  <artifactId>jaxb-xjc</artifactId>
		  <version>2.1</version>
		</dependency>
		<dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.1</version>
    </dependency>
</dependencies>
  
<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.jvnet.jaxb2.maven2</groupId>
      <artifactId>maven-jaxb2-plugin</artifactId>
      <executions>
        <execution>
          <goals>
            <goal>generate</goal>
          </goals>
          <configuration>
            <!--  if you want to put DTD somewhere else
            <schemaDirectory>src/main/jaxb</schemaDirectory>
            -->
          </configuration>
        </execution>
      </executions>
      <dependencies>
        <dependency>
          <groupId>org.jvnet.jaxb2-commons</groupId>
          <artifactId>property-listener-injector</artifactId>
          <version>1.0</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

The important thing to know is that you have to generate your classes with one schema each time. If you put webapp schemas 2.2 and 2.3 in the same time,
you will obtain errors. Be sure to include all the files related to your webapp schema to generate your java classes.

Example : webapp 2.4 need
web-app_2_4.xsd
j2ee_1_4.xsd
jsp_2_0.xsd

You can even do some customization with a config file named : domain.jaxb (/src/main/resources).

To generate from DTD

In your pom.xml, you will have to add this.

<dependencies>
  <dependency>
	  <groupId>com.sun.xml.bind</groupId>
	  <artifactId>jaxb-xjc</artifactId>
	  <version>2.0</version>
	</dependency>
	<dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.0</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.jvnet.jaxb2.maven2</groupId>
      <artifactId>maven-jaxb2-plugin</artifactId>
      <executions>
        <execution>
          <goals>
            <goal>generate</goal>
          </goals>
          <configuration>
            <!--  if you want to put DTD somewhere else
            <schemaDirectory>src/main/jaxb</schemaDirectory>
            -->
            <extension>true</extension>
            <schemaLanguage>DTD</schemaLanguage>
            <schemaIncludes>
              <schemaInclude>*.dtd</schemaInclude>
            </schemaIncludes>
            <bindingIncludes>
              <bindingInclude>*.jaxb</bindingInclude>
            </bindingIncludes>
            <args>
              <arg>-Xinject-listener-code</arg>
            </args>
          </configuration>
        </execution>
      </executions>
      <dependencies>
        <dependency>
          <groupId>org.jvnet.jaxb2-commons</groupId>
          <artifactId>property-listener-injector</artifactId>
          <version>1.0</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>


The DTD generation is the same pattern as XSD. The principal differences are in the pom.xml

You can download a complete project that use webapp xsd and dtd to parse any web.xml. It could be useful when you want to keep it simple :)

You can browse the code from : my Kenai repository
 

PHP on Grizzly with JSR223

E-mail Print PDF

This time I will show you how to run PHP applications on GrizzlyWebServer using 100% pure java solutions.
I used Caucho Quercus to handle the PHP and GrizzlyWebServer as my WebServer.

The first implementation that I did was really simple. I used the demo that I did for JSPOnGrizzly and replace the servlet
by Quercus. You can see what the code looks like :

public void launch(){
		GrizzlyWebServer ws = new GrizzlyWebServer(80);
		
		try {
            ServletAdapter sa = new ServletAdapter();
            sa.setContextPath("/");
            
            Servlet servlet = (Servlet)ClassLoaderUtil.load("com.caucho.quercus.servlet.QuercusServlet");
    	      sa.setServletInstance(servlet);
            
    	      ws.addGrizzlyAdapter(sa, new String[]{});
            ws.start();
        } catch (Exception e){
            s_logger.error("Error Launching GrizzlyWebServer",e);
        }
}

I was expecting that would work within a few seconds, but I got few exceptions when I tried to run the application.

2009-02-02 17:28:03 com.sun.grizzly.http.servlet.ServletAdapter service
GRAVE: service exception:
java.lang.UnsupportedOperationException: Not supported yet.
	at com.sun.grizzly.http.servlet.HttpServletRequestImpl.getRealPath(HttpServletRequestImpl.java:624)
	at com.caucho.quercus.servlet.QuercusServletImpl.getPath(QuercusServletImpl.java:244)
	at com.caucho.quercus.servlet.QuercusServletImpl.service(QuercusServletImpl.java:112)
	at com.caucho.quercus.servlet.QuercusServlet.service(QuercusServlet.java:407)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	at com.sun.grizzly.http.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:174)
	at com.sun.grizzly.http.servlet.FilterChainImpl.invokeFilterChain(FilterChainImpl.java:123)
	at com.sun.grizzly.http.servlet.ServletAdapter.service(ServletAdapter.java:254)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:165)
	at com.sun.grizzly.http.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:653)
	at com.sun.grizzly.http.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:570)
	at com.sun.grizzly.http.DefaultProcessorTask.process(DefaultProcessorTask.java:840)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:153)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:136)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:103)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:89)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:67)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
	at java.util.concurrent.FutureTask.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Grizzly doesn't completely implement HttpServletRequest (yet). The easy way doesn't always work the first time.
BUT there is still a way to do PHP with GrizzlyWebServer. An alternative is to use Quercus's JSR223 implementation.

We will have to replace QuercusServlet by my Servlet that uses Quercus libraries.

Servlet servlet = (Servlet)ClassLoaderUtil.load("ca.sebastiendionne.grizzly.servlet.QuercusHttpServlet");

QuercusHttpServlet

package ca.sebastiendionne.grizzly.servlet;

import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QuercusHttpServlet extends HttpServlet {
	private static final long serialVersionUID = -1649882114668014299L;
	
	private static final Logger s_logger = LoggerFactory.getLogger(QuercusHttpServlet.class);
	
	private static ScriptEngineManager scriptManager = new ScriptEngineManager();
	private static ScriptEngine phpEngine = scriptManager.getEngineByExtension("php");
	
	@SuppressWarnings("unchecked")
	protected void doPut (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		
		ScriptContext context = phpEngine.getContext();

		try {
			context.setWriter(new StringWriter());
			
			//put the parameters and attributes into the engine
			Enumeration attributes = req.getAttributeNames();
			
			while (attributes.hasMoreElements()) {
				String key = (String) attributes.nextElement();
				
				// put the parameters and attributes into the engine
				phpEngine.put(key, req.getAttribute(key));
			}
			
			Map<String, Object> params = req.getParameterMap();
			
			for (Iterator iterator = params.keySet().iterator(); iterator.hasNext();) {
				String key = (String) iterator.next();
				
				// put the parameters and attributes into the engine
				phpEngine.put(key, params.get(key));
			}
			
			// need a better way to find the requested file
			String uri = req.getRequestURI();
			
			if(uri.startsWith("/")){
				uri = uri.substring(1);
			}
			
			phpEngine.eval(new FileReader(uri), context);
			StringWriter writer = (StringWriter) context.getWriter();
			res.getWriter().println(writer.toString());
		} catch (Exception e) {
			s_logger.error("Error Evaluating PHP",e);
		}
		
	}
	
	protected void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		doPut(req, res);
	}

}

We need a php page to test our application.
phpinfo.php

<?php

// Show all information, defaults to INFO_ALL
phpinfo();

?>

The output won't be the same as the native php. Here the output from Quercus implementation.

Quercus
PHP Version => 5.2.0
System => Windows XP 5.1 x86
Build Date => 20070628T2777
Configure Command => n/a
Server API => CGI
Virtual Directory Support => disabled
Configuration File (php.ini) Path => WEB-INF/php.ini
PHP API => 20031224
PHP Extension => 20041030
Debug Build => no
Thread Safety => enabled
Registered PHP Streams => php, file, http, https
Variable => Value
....

You can download the source code for this project here.
 

JSP On Grizzly

E-mail Print PDF

We had a lot of people that ask how to put JSP over Grizzly, but we didn't have a implementation or a working sample to show them.
It couldn't stay like that for ever ... so I took a little of my spare time and I got something for you :)

I'll show you how to to compile your JSP with Jasper and use them with GrizzlyWebServer.
I used Jasper that came with Tomcat 6. I'll need to include some librairies to your project.
I didn't try with Tomcat 4.x, but maybe you could save some space.
I'll skip the jars required for Jasper to the end of this article. Now let's take a look at the beast (ok, mini-beast).

The JSP page is really simple. If you want to use framework like Struts, you will have more work to do, but I won't cover that.

<html>
	<body>
		
		Hello to you : 
		<table>
			<tr>
		<% for(int i=0;i<5;i++){%>
			<td><%=i%></td>
		<%}%>
		</tr>
	</table>
	</body>	
</html>

We need to compile the JSP if we want to use it with our GrizzlyWebServer. It isn't really complicated.

public void compileJSP(String[] params) throws Exception {
		JspC jasper = new JspC();
		
		jasper.setArgs(params);
		jasper.execute();
}

...  

String jasperParams[] = new String[]{
				"-webapp", 
				"./jsp",
				"-v",
				"-p", 
				"ca.sebastiendionne", 
				"-d", 
				"./classes", 
				"-l", 
				"-s", 
				//"-webxml", // if you want JSPC to generate a webxml
				//"./web_jasper.xml", 
				"-compile"};

//compile the JSP
compileJSP(jasperParams);

That will generate the welcome_jsp.java and compile into /classes. Now we need to call it in our application.

public void launch(){
		GrizzlyWebServer ws = new GrizzlyWebServer(80);
		
		try {
            ServletAdapter sa = new ServletAdapter();
            sa.setContextPath("/");
            
            // need to load JspRuntimeContext
            Class.forName("org.apache.jasper.compiler.JspRuntimeContext");
            
            Servlet servlet = (Servlet)ClassLoaderUtil.load("ca.sebastiendionne.welcome_jsp");
    	      sa.setServletInstance(servlet);
            
    	      ws.addGrizzlyAdapter(sa, new String[]{});
            ws.start();
        } catch (Exception e){
            s_logger.error("Error Launching GrizzlyWebServer",e);
        }
}

The final touch is to test it. You will obtain a very nice output :) http://localhost

Hello to you :
0 	1 	2 	3 	4

I didn't go to deep into JSPC. I used JSPC, the class used by the Ant task. So because of that, we will need
to include Ant jars into the project. If you have problems with that, I'm sure that you could extract the code from
the ant task too.
The jars needed are :

ant-launcher.jar // from ant 1.7x
ant.jar // from ant 1.7x
el-api.jar // from Tomcat 6.x
jasper-el.jar // from Tomcat 6.x
jasper-jdt.jar // from Tomcat 6.x
jasper.jar // from Tomcat 6.x
jsp-api.jar // from Tomcat 6.x
servlet-api.jar // from Tomcat 6.x
tomcat-juli.jar // from Tomcat 6.x : for the logging into JSPC

You can download the source code here.
Last Updated ( Thursday, 29 January 2009 13:45 )
 

Grizzly : Drop connection for banned IP

E-mail Print PDF

I want to show you how you can block IPs in your Grizzly server. I pretty sure that you can found lot of reasons why you could want that.
I'll use a list from http://iblocklist.com/ as input for my demo.
What you have to do to close the connection from client that isn't wanted is pretty simple.

    Controller controller = new Controller();
    TCPSelectorHandler tcpSelectorHandler = new TCPSelectorHandler(){
        public SelectableChannel acceptWithoutRegistration(SelectionKey key) throws IOException {
            ServerSocketChannel server = (ServerSocketChannel) key.channel();
            SocketChannel channel = server.accept();
            
            if (isAddressBanned(channel.socket().getInetAddress()))  {
                if(s_logger.isDebugEnabled()){
                  s_logger.debug("This IP [" + channel.socket().getInetAddress() + 
                  "] is banned, the connection will be close");
                }
                closeChannel(channel);
                return null;
            }

            return channel;
        }
    };
    tcpSelectorHandler.setPort(port);
    controller.addSelectorHandler(tcpSelectorHandler);

With that, as soon as a connection is made, Grizzly will valid if the IP is valid and close the connection is required.
I won't show the implementation of "isAddressBanned", because is not really related to Grizzly, but you can find it in the source code.
You can download the complete source code from here.
Last Updated ( Thursday, 22 January 2009 21:42 )
 

Template Code Generator Part 2 : FreeMarker

E-mail Print PDF

In my previous post, I covered Apache Velocity, Eclipse JET/JET2.
I got a suggestion to look the framework FreeMarker.

FreeMarker look like Velocity. You can even find converters : Velocity -> FreeMarker.
I'll describe in this part how to create the same output but using FreeMarker.

Take a look at the generate method.

SampleFreeMarker.java

  public void generate() {

    try {
      Configuration cfg = new Configuration();
      
      cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);

      Template tpl = cfg.getTemplate("./templates/GalleryTemplateFreeMarker.ftl");
      OutputStreamWriter output = new OutputStreamWriter(System.out);
      
      Map root = new HashMap();
      
      root.put("list", mediaFileList);
      
      tpl.process(root, output);
      
    } catch (Exception e) {
      s_logger.error("generate", e);
    }

  }



Let's compare to the Velocity implementation.

SampleVelocity.java

  public void generate() {

    try {
      Velocity.init();

      VelocityContext context = new VelocityContext();
      context.put("list", mediaFileList);

      Template template = Velocity.getTemplate("./templates/GalleryTemplateVelocity.vm");

      BufferedWriter writer = writer = new BufferedWriter(new OutputStreamWriter(System.out));

      if (template != null)
        template.merge(context, writer);

      /*
       * flush and cleanup
       */

      writer.flush();
      writer.close();
      
    } catch (Exception e) {
      s_logger.error("generate", e);
    }

  }



The main difference is with FreeMarker you need to create a root HashMap and put the objects in it.
With Velocity you put the objects within the context.

Now see the FreeMarker template.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
 <html> 
  <head>
    <!-- include the required JavaScript file --> 
  </head>
 
 <body>
  <div align="center">
    <table width="80%">
<#assign maxItembyRow = 2>
<#assign index = 0>
<#assign count = 0>
<#assign newLine = true>
<#foreach mediaFile in list>
  <#if newLine>
      <tr>
  <#assign newLine = false>
  </#if>
        <td>
            <a href="/${mediaFile.name}" id="player${count}">
            </a>
        </td>
  <#if index < maxItembyRow-1>        
    <#assign index = index + 1>
  <#else>
    <#assign index = 0>
    <#assign newLine = true>
  </#if>
  <#if newLine>
      </tr>
  </#if>
  <#assign count = count + 1>
</#foreach>
    </tr>
  </table>
  </div>
  </body>
</html> 


It's almost the same as Velocity except that the syntax change a little.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
 <html> 
  <head>
    <!-- include the required JavaScript file --> 
  </head>
 
 <body>
  <div align="center">
    <table width="80%">
#set( $maxItembyRow = 2)
#set( $index = 0)
#set( $newLine = true)
#foreach( $mediaFile in $list )
#if( $newLine )
    <tr>
#set( $newLine = false)
#end
#if( $index<$maxItembyRow )
        <td><a href="/$mediaFile.name" id="player$velocityCount"> 
            </a>
        </td>
#set($index = $index+1)
#else
#set($index = 0)
#set( $newLine = true)
#end
#end
    </tr>
  </table>
  </div>
  </body>
</html> 


What I didn't like about FreeMarker is the lack of documentation.
There had good javadoc, but something you need more than that like "real life" samples.
The source code can be downloaded here.
Last Updated ( Sunday, 11 January 2009 16:21 )
 

Template Code Generator : Apache Velocity - JET - JET2

E-mail Print PDF

I wanted to use a template as input for my Code Generator, but the problem was to find one that worked in a stand alone mode, not a web based one. In my research a found few that do what I wanted. Apache Velocity and Eclipse JET/JET2.

I'll explain in details theses Template Code Generator with a little application. I'll create a web page as output.

Here the specs for the demo.

- The web page template should create a entry for each items in the list received in parameter
- The list could be created dynamically (so the number of items is not fixed)

Before starting to explain how to do it with theses frameworks, I'll use a class : MediaFile that contains the info on a media file. I'll create a html that display 2 items by row and just to kept the demo simpler, I'll use a even number of items.

Take a look at the html that I would like to generate.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
 <html> 
  <head>
    <!-- include the required JavaScript file --> 
  </head>
 
 <body>
  <div align="center">
    <table width="80%">
        <tr>
            <td>
              <a href="/name1" id="player1">name1 
              </a> 
            </td>
            <td>
              <a href="/name2" id="player2">name2
              </a> 
            </td>
        </tr>
        <tr>
            <td>
              <a href="/name3" id="player3">name3
              </a> 
            </td>
            <td>
              <a href="/name4" id="player4">name4
              </a> 
            </td>
        </tr>
        <tr>
            <td>
              <a href="/name5" id="player5">name5
              </a> 
            </td>
            <td>
              <a href="/name6" id="player6">name6 
              </a> 
            </td>
        </tr>
    </table>
  </div>
  </body>
</html> 

I didn't put <td> and <a> on the same line on purpose. The reason it because it's easier to show the format's problems with a code generator. I'll explain it in more details later.

The MediaFile's list will be populated like that :

public void init() {

    mediaFileList = new ArrayList();

    for (int i = 0; i < 5; i++) {
      MediaFile mediaFile = new MediaFile();
      mediaFile.setName("name" + i);
      mediaFile.setFps("29.997");
      mediaFile.setDuration("12:45");
      mediaFile.setCodec("H264");
      mediaFile.setWidth("320");
      mediaFile.setHeight("240");
      mediaFile.setStreamSize("2 Megs");

      mediaFileList.add(mediaFile);
    }

  }

Apache Velocity

I known the framework by name, but I never used before. I have to say that it wasn't too hard to get it to work. Apache have a good documentation for Velocity API. If you are not familiar with this API, go take a look at the user guide http://velocity.apache.org/engine/devel/user-guide.html

Apache Velocity use it's own language, but it's pretty simple. What I didn't like at first was the lack of nested loop.

I wanted to do something like that (using the iterator in a nested loop):
 
 for(Iterator it = list.iterator();it.hasNext();){
   ...
      for(int i=0;i<2;i++){
        Object element = iterator.next();
        ...
      }
      ...
 }
 
 
I'm not a expert in Velocity, but after looking around on the web, I didn't find a simple answer, so I had to do it another way. The problem with a template like below, is that it could become hard to read, because if you let some blank lines for the readiness of the code, theses lines will appear in the generated code.

Let's take a look at the template in Velocity that will give the desirable layout.

GalleryTemplateVelocity.vm
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
 <html> 
  <head>
    <!-- include the required JavaScript file --> 
  </head>
 
 <body>
  <div align="center">
    <table width="80%">
#set( $maxItembyRow = 2)
#set( $index = 0)
#set( $newLine = true)
#foreach( $mediaFile in $list )
#if( $newLine )
    <tr>
#set( $newLine = false)
#end
#if( $index<$maxItembyRow )
        <td><a href="/$mediaFile.name" id="player$velocityCount">$mediaFile.name
            </a>
        </td>
#set($index = $index+1)
#else
#set($index = 0)
#set( $newLine = true)
#end
#end
    </tr>
  </table>
  </div>
  </body>
</html>
 
 
After that we need the main class that will call the template, and populate the list of MediaFile. If you want to pass variables to Velocity template, you have to put them in the context, like you do for a HttpRequest.

SampleVelocity.java

  public void generate() {

    try {
      Velocity.init();

      VelocityContext context = new VelocityContext();
      context.put("list", mediaFileList);

      Template template = Velocity.getTemplate("./templates/GalleryTemplateVelocity.vm");

      BufferedWriter writer = writer = new BufferedWriter(new OutputStreamWriter(System.out));

      if (template != null)
        template.merge(context, writer);

      /*
       * flush and cleanup
       */

      writer.flush();
      writer.close();
      
    } catch (Exception e) {
      s_logger.error("generate", e);
    }

  }

Eclipse JET

JET can be used as a template code generator. It's was made to run within Eclipse, but you can include two Eclipse jar and that will do the trick. JET is based on the JSP syntax. If you have done scriplet in JSP, you won't find that hard to use.

The main differences between JEt and Velocity, is that JET only take 1 parameter in the template. Yes, only one... You can pass that by creating a java class that will contains all your variables. Yes it's ugly, but when you know it, it's not hard to use.

The second big difference is that JET framework compile the template into a java class, and you use this class in your application.

Take a look at the JET template (look like a JSP with the 2 first lines that you related to JET.

GalleryTemplateJet.jet

<%@ jet package="ca.sebastiendionne.gallery.jet" class="GalleryHtmlJET" imports="java.util.* ca.sebastiendionne.gallery.model.*" %>
<% List<MediaFile> mediaFileList = (List<MediaFile>) argument; %>

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
 <html> 
  <head>
    <!-- include the required JavaScript file --> 
  </head>
 
 <body>
  <div align="center">
    <table width="80%">
      <% 
      
      int maxItembyRow = 2;
      int index = 0;
      
      for (Iterator<MediaFile> iterator=mediaFileList.iterator();iterator.hasNext();) {%>
        <tr>
        <%
        for(int j=0;j<maxItembyRow;j++){
          MediaFile element = iterator.next();
          %>
            <td>
            <a href="/<%=element.getName()%>" id="player<%=index%>"><%=element.getName()%> 
          </a> 
            
            <%=element%>
            
            </td>
          <%
          index++;
        }%>
        </tr>
        <%
      }
      %>
    </table>
  </div>
  </body>
</html>

That will generate the java class : ca.sebastiendionne.gallery.jet.GalleryHtmlJET

and you use it like that :

  public void generate(){
    
    GalleryHtmlJET galleryJET = new GalleryHtmlJET();
    
    String html = galleryJET.generate(mediaFileList);  // the argument is the list
    
    System.out.println(html);
  }

The method generate() is simpler and smaller than Velocity, but in other hands... The formatting is more tricky with JSP syntax. Try for fun to look at a html page generated with scriptlet. It's will works, but there will be lot of blank lines and it won't have a nice indentation. That is important when you want to generate java class. You don't want to pass a formatter after the generating job.

I had used JET few months ago for my application IbatisGen. I think that it took more time to get the indentation right that coding the rest of the application.

JET have some limitations like the one argument, but that JET2 fixed that.


Eclipse JET2

JET2 differs than JET1 in different ways. JET1 can be used outside Eclipse, but not JET2.

JET2 can be easily use in Eclipse if you have a xml file as input, but if you don't have a fixed input like this demo. It's more complicated.
You will have to create a Eclipse Plugin that will be able to handle dynamic input.

So, if you don't want to create a Eclipse Plugin, stop here, take JET or Velocity.

I won't cover how to create the JET2 Plugin, you can find a good sample here http://www.eclipse.org/articles/Article-JET2/jet_tutorial2.html, but I'll show you how to use a xml input file.

The JET2 templates can you JSP and JSLT syntax like.

sample.xml

<app class="Car">
  <property name="model" type="String" initial="Hybrid" />
  <property name="horsepower" type="int" initial="140" />
  <property name="spareTires" type="boolean" initial="true" />
</app>

The main template (like the java class that contains the main() )

main.jet

<%@taglib prefix="ws" id="org.eclipse.jet.workspaceTags" %>
<c:if test="isVariableDefined('org.eclipse.jet.resource.project.name')">
    <ws:file template="templates/testCar.jet" path="{$org.eclipse.jet.resource.project.name}/dump2.xml"/>
</c:if>

testCar.jet (the template that will generate the code from sample.xml) (We are creating a getter/setter class)


<%@taglib prefix="ws" id="org.eclipse.jet.workspaceTags" %>
class <c:get select="/app/@class" /> {
<c:iterate select="/app/property" var="p" >
  private <c:get select="$p/@type" /> <c:get select="$p/@name" />;
</c:iterate>

  public <c:get select="/app/@class" />() {
  <c:iterate select="/app/property" var="p" >
    this.<c:get select="$p/@name" /> = <c:choose select="$p/@type" >
    <c:when test="'String'">"<c:get select="$p/@initial" />"</c:when>
    <c:otherwise><c:get select="$p/@initial" /></c:otherwise>
    </c:choose>
;
  </c:iterate>
  }

<c:iterate select="/app/property" var="p" >
  public void set<c:get select="camelCase($p/@name)" />(<c:get select="$p/@type" /> <c:get select="$p/@name" />) {
    System.out.println("In set<c:get select="camelCase($p/@name)" />()");
    this.<c:get select="$p/@name" /> = <c:get select="$p/@name" />;
  }
  
  public <c:get select="$p/@type" /> get<c:get select="camelCase($p/@name)" />() {
    System.out.println("In get<c:get select="camelCase($p/@name)" />()");
    return <c:get select="$p/@name" />;
  }
  
</c:iterate>
}

To run all that you need to "Run as ... JET Transformation" in Eclipse.

I won't go into details, but here what the generate() method should look like if you want to handle a dynamic input.

public void generate(){
    
    GalleryHtmlJET galleryJET = new GalleryHtmlJET();
    
    JET2Context context = new JET2Context(null);
    context.setVariable("list", mediaFileList);
    
    JET2Writer out = new BodyContentWriter();
    
    context.setTagFactory(new TagFactoryImpl(context));
    
    ... the line for the Plugin
      galleryJET.generate(context, out);
    ... end of the Plugin stuff
    System.out.println(out);
    
  }

It's look really like Apache Velocity at this point.

If I had to choose between them, I don't know if I would choose Velocity or JET. Both of them could work in a plugin (Eclipse or Netbean), support Ant task.

What do you think ? Do you know some framework that you want to share with us ?
You can download the source code here : Velocity/JET and JET2.
Last Updated ( Sunday, 04 January 2009 16:12 )
 

Grizzly : Create a server and client with only few changes

E-mail Print PDF

With Grizzly it can be simple to create a server and client with a few lines changes. I want to show you how you can create or convert a server to a client without to much troubles.

I will use ProtocolChain in the server. For the client there are two ways to create it using the logic of the server. You can use the ProtocolChain or use a CallbackHandler.

I'll show you how to create the client for the both alternatives.

Let's start by showing the main lines and later I'll show you the differences between the ProtocolChain and CallbackHandler implementations for the client.

The complete source code is available at the end of this post.


Let's take a look if the init method of the server and the clients implementations.

Server

f_tg = new ThreadGroup("ThreadGroup");

final CountDownLatch started = new CountDownLatch(1);

controller = new Controller();
TCPSelectorHandler tcpSelectorHandler = new TCPSelectorHandler();
tcpSelectorHandler.setPort(port);
controller.addSelectorHandler(tcpSelectorHandler);

Client
f_tg = new ThreadGroup("ThreadGroup");

final CountDownLatch started = new CountDownLatch(1);

controller = new Controller();
TCPSelectorHandler tcpSelectorHandler = new TCPSelectorHandler();
controller.addSelectorHandler(tcpSelectorHandler);

The difference is that you need to specify the listening port of the server.


Let's continue with the next step : the close notification and the state listener

The server and clients are identical.

BaseSelectionKeyHandler selectionKeyHandler = new BaseSelectionKeyHandler();

// to be notify when a client/server close the connection
selectionKeyHandler.setConnectionCloseHandler(new ConnectionCloseHandler() {

public void locallyClosed(SelectionKey key) {
if(s_logger.isDebugEnabled()){
s_logger.debug(key + " is being locally cancelled");
}
}

public void remotlyClosed(SelectionKey key) {
if(s_logger.isDebugEnabled()){
s_logger.debug(key + " is being remotly cancelled (connection closed)");
}
}
});

tcpSelectorHandler.setSelectionKeyHandler(selectionKeyHandler);

// STATE Listener
controller.addStateListener(new ControllerStateListenerAdapter() {

public void onException(Throwable e) {
s_logger.error("Grizzly controller exception:" + e.getMessage());
}

public void onReady() {
if(s_logger.isDebugEnabled()){
s_logger.debug("Ready!");
}
started.countDown();
}

});


Now it's time the see the ProtocolChain in the server and the client implementations

Server and client (the ProtocolChain implementation)
// the protocol chain
EchoQueryProtocolFilter protocolParser = new EchoQueryProtocolFilter();
EchoQueryManagerFilter echoManagerFilter = new EchoQueryManagerFilter(this);

final ProtocolChain protocolChain = new DefaultProtocolChain();
protocolChain.addFilter(protocolParser);
protocolChain.addFilter(echoManagerFilter);
((DefaultProtocolChain) protocolChain).setContinuousExecution(true);


ProtocolChainInstanceHandler pciHandler = new DefaultProtocolChainInstanceHandler() {

public boolean offer(ProtocolChain protocolChain) {
return false;

}

public ProtocolChain poll() {

return protocolChain;
}
};

controller.setProtocolChainInstanceHandler(pciHandler);


Client (the Callbackhandler) : nothing here.


We finish by starting the server and clients

Server

// start the server
new Thread(f_tg, controller).start();

try {
started.await();
} catch (Exception e) {
s_logger.error("Timeout in wait" + e.getMessage());
}

// extra stuff : Queue
blockingQueue = new LinkedBlockingQueue();
queueConsumer = new QueueConsumer(this, blockingQueue);
new Thread(f_tg, queueConsumer,"QueueConsumer").start();

Client
// start the client
new Thread(f_tg, controller).start();

try {
started.await();
} catch (Exception e) {
s_logger.error("Timeout in wait" + e.getMessage());
}

// extra stuff : Queue
blockingQueue = new LinkedBlockingQueue();
queueConsumer = new QueueConsumer(this, blockingQueue);
new Thread(f_tg, queueConsumer,"QueueConsumer").start();

connector_handler = (TCPConnectorHandler) controller.acquireConnectorHandler(Controller.Protocol.TCP);

The difference this time is on the client side. We need to acquire a ConnectorHandler that will be used later.


I want to say that the ProtocolChain is this example are identical for the client and server. Normally you could have a different implementations but the logic is the same. The init method will look alike.

Now let's take a deeper look into the Client implementations.


On the client side we need to add a method to connect to the server.

There is a little difference between the ProtocolChain and CallbackHandler. In the connect you need to specify a CallbackHandler.
For the ProtocolChain implementation, I was expecting the pass a null handler, and the API will use the ProtocolChain instead, but it doesn't work. I sent a email to the developers to find if it's a bug or not. I'll describe the current way that work.

UPDATED : It was a bug.  It fixed with Grizzly 1.9.3+.

Client (ProtocolChain)
public boolean connect() {
try {
//connector_handler.connect(new InetSocketAddress(host, port), new ProtocolChainCallbackHandler(connector_handler));
connector_handler.connect(new InetSocketAddress(host, port), (CallbackHandler)null); // don't need the callback anymore with 1.9.3+
 } catch (Exception e) {
s_logger.error("Exception in execute..." + e);
return false;
}

return true;
}
Client (CallbackHandler)
public boolean connect() {
try {
connector_handler.connect(new InetSocketAddress(host, port), new ClientCallbackHandler(connector_handler));
} catch (Exception e) {
s_logger.error("Exception in execute..." + e);
return false;
}

return true;
}

The last part is the CallbackHandler. I'll start by the ProtocolChain implementation followed by the CallbackHandler implementation. I'll describe
the difference between the implementations, I suggested that you take a look at the source code to get the full overview.


ProtocolChainCallbackHandler
// read event
public void onRead(IOEvent ioEvent) {
SelectionKey key = ioEvent.attachment().getSelectionKey();
SelectorHandler selectorHandler = ioEvent.attachment().getSelectorHandler();

// CALL THE PROTOCOL CHAIN
try {
if(key.isValid() && key.isReadable()){
Context ctx = ioEvent.attachment();

ctx.getProtocolChain().execute(ioEvent.attachment());

}
} catch (Exception ex){
if(s_logger.isDebugEnabled()){
s_logger.debug("IOException", ex);
}
selectorHandler.getSelectionKeyHandler().cancel(key);
}

}

ClientCallbackHandler
// read event
public void onRead(IOEvent ioEvent) {
SelectionKey key = ioEvent.attachment().getSelectionKey();
SelectorHandler selectorHandler = ioEvent.attachment().getSelectorHandler();
SocketChannel socketChannel = (SocketChannel)key.channel();

try {
if(key.isValid() && key.isReadable()){

// parse the responses here
int count = socketChannel.read(response);
if(count>0){
response.flip();

byte[] b = new byte[(int)count];
response.get(b);

// ...... do your own logic. You can use EchoQueryProtocolParser as example

response.clear();
if(s_logger.isDebugEnabled()){
s_logger.debug(new String(b)); // for debug purpose
}
}

selectorHandler.register(key, SelectionKey.OP_READ);
}
} catch (IOException ex){
if(s_logger.isDebugEnabled()){
s_logger.debug("IOException", ex);
}
selectorHandler.getSelectionKeyHandler().cancel(key);
}

}
I hope that can show you that with Grizzly it can be really simple to create a server and a client in the same time with just few changes. The source code can be downloaded here.
Last Updated ( Monday, 05 January 2009 19:34 )
 

Tools for debugging html/css/javascript

E-mail Print PDF

There are so many browsers and version of theses browsers that I became harder to create HTML that will run on all the possibles combinations.

You need the appropriate tools to help you to debug. There are few application and plugins you need to try :

- Firebug for Firefox (https://addons.mozilla.org/fr/firefox/addon/1843) : to debug everything : html, css, javascript, ajax ...

- Markup Validation Service (http://validator.w3.org/) : to validate your (x)html page.

- Internet Explorer Developer Toolbar (http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en) :

Microsoft Firebug alternative : to debug html, css ...

- Install multiple versions of IE on your PC (http://tredosoft.com/Multiple_IE) : Install more than one version of IE on your PC.

- CSS Formatter and Optimiser (http://floele.flyspray.org/csstidy//css_optimiser.php?lang=en) : a nice CSS formatter and optimiser.

-I also recommend trying IETester (http://www.my-debugbar.com/wiki/IETester/HomePag) which allows you to open browser tabs with individual IE engines.

I like this even a little bit better than MultipleIE,

which is a very cool package but caused me some problems while IETester just ran out of the box.

Theses are the tools that I'm using to debug the main page of Glassfish. Even with that.. it's hard :)

Last Updated ( Monday, 22 December 2008 13:36 )
 

Maven Test Coverage : Cobertura and Surefire working

E-mail Print PDF

I wanted to add Cobertura to Grizzly project within the pom file for Maven, but I got errors at first. I follow the procedure describe on Cobertura website,

but it was lacking of a complete example. Cobertura will instrument your classes and you need to run tests to get a test coverage.

You need to pass the path of these instrumented classes to the plugin that will run the tests(in the same pattern for ant and junit).

For my project I'm using Surefire. I created a file pom2.xml for Grizzly.

Put this file in the root of the project and call it like that : mvn -f pom2.xml cobertura:cobertura

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>com.sun.grizzly</groupId>
<artifactId>grizzly-project</artifactId>
<version>1.9.0-SNAPSHOT</version>
<relativePath>pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sun.grizzly</groupId>
<artifactId>grizzly-framework</artifactId>
<version>${grizzly-version}</version>
<name>grizzly-framework</name>
<url>https://grizzly.dev.java.net</url>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<property>
<name>net.sourceforge.cobertura.datafile</name>
<value>target/cobertura/cobertura.ser</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</reporting>
</project>

I put explicit version of the plugins. You can remove that to use the latest version.

 


Last Updated ( Monday, 22 December 2008 13:38 )
 

Grizzly : Speedup the ProtocolFilter response time

E-mail Print PDF

Suppose that you are dealing with sql query that you send to a database.  Some query could take few seconds to run, that will block a Thread.

Even if you have few Threads in your pool, they could all be stuck there too.

To avoid that you can use the Producer/Consumer pattern.

Take a look at this snippets.


....

// default Pipeline settings
Pipeline pipeline = new DefaultPipeline();
pipeline.setMaxThreads(5);
controller.setPipeline(pipeline);

// the ParserProtocolFilter that will parse the query
QuoteQueryProtocolFilter protocolParser = new QuoteQueryProtocolFilter();

// the ProtocolFilter that will process the query
QuoteQueryManagerFilter quoteManagerFilter = new QuoteQueryManagerFilter();

final ProtocolChain protocolChain = new DefaultProtocolChain();
protocolChain.addFilter(protocolParser);
protocolChain.addFilter(quoteManagerFilter);

....

Suppose we want to simulate a waiting IO, you can do a sleep for 30 seconds. 
The effect will be that the manager will wait

public class QuoteQueryManagerFilter implements ProtocolFilter {

public boolean execute(Context context) throws IOException {
String query = (String) context.removeAttribute(ProtocolParser.MESSAGE);

......

// that will simulate that the database take 30 sec to complete the query
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}

// call the database
//databaseManager.execute(query);

return true;

}

If you send 10 query to your application, the application will block after 5 query (pipeline threads). 
The 6th query will be executed after 30 sec.

We can change that behaviour easily. 

We will need a Producer and a Consumer with a queue.  You can take a LinkedBlockingQueue as a queue. 

Here the snippets for the Consumer : (the Thread.sleep is only for testing)

public class Consumer implements IConsumer, Runnable {

protected BlockingQueue<String> blockingQueue;
....

public void run(){
.....
while(!Thread.currentThread().isInterrupted()){
try {
String query = blockingQueue.take();

System.out.println("     took item=" + query);
// now call your database
// that will simulate that the database take 30 sec to complete
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
databaseManager.process(command);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
.....
}

For the Producer, I use my databaseManager.

public class DatabaseManager {

protected BlockingQueue<QueueCommand> blockingQueue;
....

public void init(){

ThreadGroup tg = new ThreadGroup("Producer/Consumer");
quoteConsumer = new QuoteConsumer(this, blockingQueue);
new Thread(tg, quoteConsumer,"QuoteConsumer").start();

}


public void addtoQueue(String query) {
System.out.println("add item=" + query);
blockingQueue.add(query);
}

....
}

and don't forget the change the QuoteQueryManagerFilter  :

public boolean execute(Context context) throws IOException {
String query = (String) context.removeAttribute(ProtocolParser.MESSAGE);

......

// call the database
databaseManager.addToQueue(query);

return true;

}

If you try this, the database will still take 30 seconds to run, but your application will be able to handle the requests.

Last Updated ( Monday, 22 December 2008 13:44 )
 

Grizzly : How to be notify when a client disconnect

E-mail Print PDF

It's now possible to be notify when a client disconnect for a server build on Grizzly 1.9+.

here a little snippets that will allow you that.  Thanks to the new ConnectionCloseHandler.

public void init(){

int port = 5000;

try {

Controller controller = new Controller();
TCPSelectorHandler tcpSelectorHandler = new TCPSelectorHandler();
tcpSelectorHandler.setPort(port);

Pipeline pipeline = new DefaultPipeline();
pipeline.setMaxThreads(5);

controller.setPipeline(pipeline);

BaseSelectionKeyHandler selectionKeyHandler = new BaseSelectionKeyHandler();

// to be notify when a client close the connection
selectionKeyHandler.setConnectionCloseHandler(new ConnectionCloseHandler() {

public void locallyClosed(SelectionKey key) {
System.out.println(key + " is being locally cancelled");
}

public void remotlyClosed(SelectionKey key) {
System.out.println(key + " is being remotly cancelled (connection closed)");
}
});

tcpSelectorHandler.setSelectionKeyHandler(selectionKeyHandler);

controller.addSelectorHandler(tcpSelectorHandler);

..... add here your protocolChain

try {
controller.start();
} catch (IOException e) {
e.printStackTrace();
}

} catch (Exception e) {
System.out.println("exit");
}
}
 

Read web.xml with one line of code

E-mail Print PDF

I needed to parse a web.xml for a sample for Grizzly and I wanted to find a way to have something that I can reuse later.  You don't have to do it by hand.  There are tools out there to do it for you.


One of them is XMLBeans from Apache group and more popular is JAXB.  For JDK 1.4 ,I used XMLBeans and if you have JDK6 JAXB will reduce the dependencies and will be more smaller.  I'll show you how to use theses two API.


XMLBEANS

What I like about this tool is that I can generate Java classes from a xsd within seconds using Ant. 

I want to show you how to obtain a Class that will contains a web.xml loaded with only one line of code :)


Let's start by downloading XMLBeans.  I'll skip to the folder structure I'll use for this demo.


lib/                   : Where you put the XMLBeans libraries
schemas/         : Where you put the xsd
build.xml         


Download build.xml from here.

I use the schemas from Glassfish sources : glassfish/appserv-commons/schemas


You don't have to copy all the files.  Copy just the main schemas and Ant will download the missing schemas.


For my demo I used theses files :

schemas/j2ee_1_4.xsd
schemas/jsp_2_0.xsd
schemas/web-app_2_4.xsd


you just have to launch the ant task with this command :

ant -autoproxy 


that will generate a jar file and the java source for theses schemas.


Now.. How do we load a web.xml within our Java application ?

#1 - Include the jar file : j2ee_schemas-xmlbeans.jar into your project
#2 - Create the root class of your schema and load the web.xml

WebAppDocument webAppDocument = WebAppDocument.Factory.parse(webxmlFile);

After that .. It's up to you,   webAppDocument contains all the config from web.xml.

JAXB

You will need the librairies for the compilation, but after that if you use JDK6, you can remove them, because JAXB is include in JDK6.

#1 - To generate the schemas, you use ant.
#2 - Include the jar file : j2ee_schemas-jaxb.jar into your project
#3 - Create the root class of your schema and load the web.xml

JAXBContext jc = JAXBContext.newInstance("ca.sebastiendionne.jaxb.xsd");

// create an Unmarshaller
Unmarshaller u = jc.createUnmarshaller();

JAXBElement root =    (JAXBElement)u.unmarshal( new FileInputStream("./web.xml") );

WebAppType webAppType = (WebAppType)root.getValue();

It's take a little more line of code, but it's not complicated.


I put the source project (xmlbeans + jabx) here.


Last Updated ( Monday, 22 December 2008 13:35 )
 
  • «
  •  Start 
  •  Prev 
  •  1 
  •  2 
  •  Next 
  •  End 
  • »


Page 1 of 2