Friday, March 30, 2012

My ZK + Jetty Project

Here are some notes for my own development:

Installation

Download ZK CE Version (LGPL)
http://www.zkoss.org/download/zk

Install ZK Studio (Eclipse Plugin)
http://www.zkoss.org/documentation/zkstudio

  • Note that by default ZK Studio comes with the ZK EE Version (60 days Trial). You may change the build setting to the CE version later on.


Install Jetty (I prefer Jetty over Tomcat)
http://download.eclipse.org/jetty/

  • I am using version 8 in my project.


Jetty WTP Plugin
http://wiki.eclipse.org/Jetty_WTP_Plugin/Jetty_WTP_Install

  • You will need this in order to have the "Server Adapter" for Jetty version 7/8 configured in Eclipse.
  • Preferences > Servers > Runtime Environments > Add...


Create Server Console

  • Open the Servers window. Right click > New > Server
  • To associate a project with the server (auto-deploy/synchronized), right click the server and choose [Add and Remove].




** 1. WTP Plugin has some bugs that it does not add all Jetty's JAR file to classpath. You may encounter ClassNotFoundException during the server start. You can manually add them back by double-click the server and choose [open launch configuration]. Then [Add External JARs] to the classpath.

Typically, it misses out these two jars:

  • javax.annotation
  • org.objectweb.asm





Dependency Management - Apache Ivy

  • It is pretty easy to get start with Ivy. In eclipse, you can install the IvyDE plugin from the marketplace. Then create your own ivy.xml to specifiy the necessary dependencies.
  • If you want to change the default Ivy setting, create ivysettings.xml and specify the properties to be changed according to the online reference.
  • Both files can be put in the root directory of your eclipse project, and you can point to their locations in the IvyDE setting.
  • You may want to have all dependencies (*.jar) to be exported to the WAR at your final deployment. Simply add this entry to your deployment setting.




Development

Basic Concepts
  • Component is a visual element in ZUL, such as <button>, <label>...etc. This POJO represents the View of MVC pattern.
  • Composer is interface that control the component, and so it is the Controller of MVC pattern.













Friday, March 16, 2012

GAE Logging

By default GAE's admin console supports fine control of the Java Logging Framework (JDK Logging). The configuration format can be learnt from the ${JDK_HOME}/lib/logging.properties file.

http://code.google.com/intl/en/appengine/docs/java/runtime.html#Logging

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/logging/LogManager.html

Wednesday, March 14, 2012

GAE in Action


Some Concerns in using GAE as your Backend
  1. No sockets. The API does not allow Java sockets. You may use URLFetch API instead.
  2. No relational database, not even deploying a sqlite db as resource file due to the read-only restriction of resource file in GAE. (This is not true now as Google is rolling out Cloud SQL API which support MySQL-like relational database.)
  3. HTTP response/request data size limits : 10MB each

Facebook JavaScript SDK
http://developers.facebook.com/docs/reference/javascript/

The Unofficial Google App Engine Price Change FAQ
http://blorn.com/post/10013293300/the-unofficial-google-app-engine-price-change-faq

Scheduled Tasks With Cron for Java
http://code.google.com/intl/en/appengine/docs/java/config/cron.html

SEO Tutorial Subjects Covered


SEO Tutorial Subjects Covered

1. Business and Domain Name Choice : You might think what’s the name of my business got to do with search engine optimization (SEO)? If you choose the correct business and domain name in the first place it makes the whole optimization process so much easier….
2. WebSite Optimization : In this section of our SEO Tutorial we’ll broadly introduce on site optimization, how to optimize your web site for better search engine rankings with good Google rankings our primary goal….
3. Title Optimization : The TITLE element of your web page (found within the HEAD) is very important, probably the most important part of a page (especially for placement in Google and Yahoo) and should ideally be optimized for a small number of keywords or phrases….
4. Meta Tags Optimization : There used to be a time when the contents of a pages Meta Tags was very important, it was around about the same time the Berlin Wall was still standing!! Today meta tags hold little value to Search Engine Optimization (SEO)….
5. Anchor Text Optimization : Google (and to a lesser degree other search engines) heavily weight it’s Search Engine Results Pages (SERPs) towards the anchor text of links to a page. This can be demonstrated by looking at extreme examples where a pages high ranking can only be attributed to anchor text and no other SEO factors….
6. SERPs Competition : Your websites Search Engine Results Pages (SERPs) are determined by various SEO factors, on page content (your body text, the title element etc…), anchor text of links to your web sites pages, the search engines algorithms tweak of the day and of course the number of websites/pages competing for that search phrase. In this section of the SEO Tutorial we’ll deal with estimating the number of competitors for a SERP….
7. PageRank PR : PageRank or PR for short seems to be misunderstood by so many that this part of our SEO Tutorial we will try to explain the ins and outs of PageRank without getting too technical….
8. Google Sandbox Effect : A lot has been written about the so called Google Sandbox Effect in SEO forums over the last year or so, but not much of it is backed up by reality or facts. Find out what the sandbox really is….

Monday, March 12, 2012

Servlet Lifecycle

How do servlets work? Instantiation, session variables and multithreading
http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading


ServletContext

When the servletcontainer (like Apache Tomcat) starts up, it will deploy and load all webapplications. When a webapplication get loaded, the servletcontainer will create the ServletContext once and keep in server's memory. The webapp's web.xml will be parsed and every ServletFilter andListener found in web.xml will be created once and kept in server's memory as well. When the servletcontainer shuts down, it will unload all webapplications and the ServletContext and allServletFilter and Listener instances will be trashed.

HttpServletRequest and HttpServletResponse

The servletcontainer is attached to a webserver which listens on HTTP requests on a certain port number, which is usually 80. When a client (user with a webbrowser) sends a HTTP request, the servletcontainer will create new HttpServletRequest and HttpServletResponse objects and pass it through the methods of the already-created Filter and Servlet instances whose url-patternmatches the request URL, all in the same thread.
The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body (usually with HTML content from a JSP file). When the HTTP response is committed and finished, then both the request and response objects will be trashed.

HttpSession

When a client visits the webapp for the first time and/or the HttpSession is to be obtained for the first time by request.getSession(), then the servletcontainer will create it, generate a long and unique ID (which you can get by session.getId()) and store it in server's memory. The servletcontainer will also set a Cookie in the HTTP response with JSESSIONID as cookie name and the unique session ID as cookie value.
As per the HTTP cookie specification (a contract a decent webbrowser and webserver has to adhere), the client (the webbrowser) is required to send this cookie back in the subsequent requests as long as the cookie is valid. Using a HTTP header checker tool like Firebug you can check them. The servletcontainer will determine every incoming HTTP request header for the presence of the cookie with the name JSESSIONID and use its value (the session ID) to get the associated HttpSession from server's memory.
The HttpSession lives as long until it has not been used for more than the time as you can specify in<session-timeout> setting in web.xml, which defaults to 30 minutes. So when the client doesn't visit the webapp anymore for over 30 minutes, then the servletcontainer will trash the session. Every subsequent request, even though with the cookie specified, will not have access to the same session anymore. The servletcontainer will create a new one.
On the other hand, the session cookie has on the client side a default lifetime which is as long as the browser instance is running. So when the client closes the browser instance (all tabs/windows), then the session will be trashed at the client side. In a new browser instance the cookie associated with the session won't be send anymore. A new request.getSession() would return a brand newHttpSession and set a cookie with a brand new session ID.

In a nutshell

  • The ServletContext lives as long as the webapp lives. It's been shared among all requests in allsessions.
  • The HttpSession lives as long as the client is interacting with the webapp with the same browser instance and the session hasn't timed out at the server side yet. It's been shared among allrequests in the same session.
  • The HttpServletRequest and HttpServletResponse lives as long as the client has sent it until the complete response (the webpage) is arrived. It is not been shared elsewhere.
  • Any ServletFilter and Listener lives as long as the webapp lives. They are been shared among all requests in all sessions.
  • Any attribute which you set in ServletContextHttpServletRequest and HttpSession will live as long as the object in question lives.

Threadsafety

That said, your major concern is possibly threadsafety. You should now have learnt that Servlets and filters are shared among all requests. That's the nice thing of Java, it's multithreaded and different threads (read: HTTP requests) can make use of the same instance. It would otherwise have been too expensive to recreate it on every request.
But you should also realize that you should never assign any request or session scoped data as aninstance variable of a servlet or filter. It would going to be shared among all other requests in other sessions. That's threadunsafe! The below example illustrates that:
public class MyServlet extends HttpServlet {

    private Object thisIsNOTThreadSafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadSafe;

        thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
        thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
    } }

See also: