Wednesday, November 29, 2006

MySQL at Google

Look at that ! Google is among MySQL AB customers ! Some people say that Google AdWords application is build on MySQL backend. I'm afraid to imagine HOW it is built. But it is simply amazing ! No Oracle, DB2 or other very cool stuff. Open Source rocks !

Friday, November 24, 2006

Online syntax highlighting

It is just nice thing : http://tohtml.com

Python and MySQL

I know how to work with JDBC in Java and DBI in perl.
But how about Python ? :)
Lets see... I have Windows box with Python 2.4 and MySQL 5.
OK. What do I need else ?
Some kind of driver, if Python-style interaction with DRBMS's
is similar to Java or Perl. I'm guess :) It is here.
So, we have "Python Database API Specification v2.0".
It is not a problem for now to write an dummy code
to play with API :


import
MySQLdb
import sys

try:
myDB = MySQLdb.connect(
host="127.0.0.1",
port=3306,user="root",
passwd="**********",
db="testdb")
cHandler = myDB.cursor()
cHandler.execute("SELECT * FROM testTable")

for a in range(cHandler.rowcount) :
result = cHandler.fetchone()
for x in range(len(result)) :
print result[x]
print "\n"

myDB.close()

except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
sys.exit(-1)

Wednesday, November 22, 2006

Google PageRank

Look at this site http://www.getrank.net. They can show you PageRank of your site. I'm interested how it's can be done... For now I know how, but can't publish the source code here since minning pageranks is against google's terms of service. But, I've got a lot of fun. Sometimes it's interesting to dig :)


It was interesting to compare some pageranks (x of 10):
http://www.microsoft.com : 10 !
http://www.linux.org : 9
http://www.freebsd.org : 9
http://www.redhat.com 9
http://www.gentoo.org 8
http://www.novell.com/linux 8

Wednesday, November 15, 2006

Refreshing page in browser: HTTP headers

Working on some task I'm interested in the way how the browser's cache is working. Especially what are particular http headers sent or not by the browser when user is refreshing the page in the browser.

So, here is my experiment. I have 3 browsers: Firefox 2.0, IE 6.0, and Opera 9.0. Opera version may be old, it's because i don't use it. I don't know better browser than Firefox, sorry Opera fans.

How we can see http headers sent by browser ? There is not only one solution here. For this purpose we can use sniffer such ethereal to watch at HTTP protocol, some addition or extension to browser (for example Live Http Headers for FF or HttpWatch for IE), or even a local proxy server. But it is possible to track such data at server side. Lets take Tomcat 5.0 and write a little of code. It will be filter that listen all incoming requests to our web application and prints http headers. So, it is some kind of spider at server side :)

The code listing of filter :

package com.mycoolcompany.filters;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class RequestDumpFilter implements Filter
{
public RequestDumpFilter() {}

public void destroy() {}

public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

System.out.println(req.getMethod()+
" "
+req.getRequestURI()+" HTTP/1.1");
Enumeration enumer = req.getHeaderNames();
String headerName = null;
while(enumer.hasMoreElements())
{
headerName = (String)enumer.nextElement();
System.out.println(headerName+
" : "
+req.getHeader(headerName));
}
chain.doFilter(request, response);
}

public void init(FilterConfig filterConfig)
throws
ServletException {}
}

url-pattern '/*' is the key. It's mean that we'll be listen to all requests for our web app.
Compile, deploy and enjoy :)
So, lets begin to dig.

Point your IE browser to http://localhost:8080/RequestDumper/
You'll get something like this at your server console :

GET /RequestDumper/ HTTP/1.1
accept : image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/x-shockwave-flash,
application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, */*
accept-language : ru
accept-encoding : gzip, deflate
user-agent : Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.2; .NET CLR 1.1.4322)
host : localhost:8080
connection : Keep-Alive

When you begin to frequently refresh te page you may notice that sometning changed :

GET /RequestDumper/ HTTP/1.1
accept : */*
accept-language : ru
accept-encoding : gzip, deflate
user-agent : Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.2; .NET CLR 1.1.4322)
host : localhost:8080
connection : Keep-Alive

Accept header become a little bit shorter ;)

If you press Ctrl-F5 the browser will send the following :

GET /RequestDumper/ HTTP/1.1
accept : */*
accept-language : ru
accept-encoding : gzip, deflate
user-agent : Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)
host : localhost:8080
connection : Keep-Alive
cache-control : no-cache

'cache-control : no-cache' - that's it !

Lets take Firefox. First request looks like this :

GET /RequestDumper/ HTTP/1.1
host : localhost:8080
user-agent : Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.8.1)
Gecko/20061010 Firefox/2.0
accept : text/xml,application/xml,application/xhtml+xml,text/html;
q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
accept-language : ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
accept-encoding : gzip,deflate
accept-charset : windows-1251,utf-8;q=0.7,*;q=0.7
keep-alive : 300
connection : keep-alive

Frequently refreshing page will change the headers :

GET /RequestDumper/ HTTP/1.1
host : localhost:8080
user-agent : Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.8.1)
Gecko/20061010 Firefox/2.0
accept : text/xml,application/xml,application/xhtml+xml,text/html;
q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
accept-language : ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
accept-encoding : gzip,deflate
accept-charset : windows-1251,utf-8;q=0.7,*;q=0.7
keep-alive : 300
connection : keep-alive
cache-control : max-age=0

'cache-control : max-age=0' - it is the difference.

Pressing Ctrl-F5 gives :

GET /RequestDumper/ HTTP/1.1
host : localhost:8080
user-agent : Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.8.1)
Gecko/20061010 Firefox/2.0
accept : text/xml,application/xml,application/xhtml+xml,
text/html;q=0.9,text/plain;
q=0.8,image/png,*/*;q=0.5
accept-language : ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
accept-encoding : gzip,deflate
accept-charset : windows-1251,utf-8;q=0.7,*;q=0.7
keep-alive : 300
connection : keep-alive
pragma : no-cache
cache-control : no-cache


We got some changes : 'pragma : no-cache' and 'cache-control : no-cache'.
And finally Opera.
First request:

GET /RequestDumper/ HTTP/1.1
user-agent : Opera/9.00 (Windows NT 5.2; U; en)
host : localhost:8080
accept : text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
accept-language : en
accept-encoding : deflate, gzip, x-gzip, identity, *;q=0
connection : Keep-Alive, TE
te : deflate, gzip, chunked, identity, trailers

Frequently refreshing page will change the headers :

GET /RequestDumper/ HTTP/1.1
user-agent : Opera/9.00 (Windows NT 5.2; U; en)
host : localhost:8080
accept : text/html, application/xml;q=0.9,
application/xhtml+xml, image/png, image/jpeg,
image/gif, image/x-xbitmap, */*;q=0.1
accept-language : en
accept-encoding : deflate, gzip, x-gzip, identity, *;q=0
cache-control : no-cache
connection : Keep-Alive, TE
te : deflate, gzip, chunked, identity, trailers

'cache-control : no-cache' - new.

Pressing Ctrl-F5 :

GET /RequestDumper/ HTTP/1.1
user-agent : Opera/9.00 (Windows NT 5.2; U; en)
host : localhost:8080
accept : text/html, application/xml;q=0.9,
application/xhtml+xml, image/png, image/jpeg,
image/gif, image/x-xbitmap, */*;q=0.1
accept-language : en
accept-encoding : deflate, gzip, x-gzip, identity, *;q=0
cache-control : no-cache
connection : Keep-Alive, TE
te : deflate, gzip, chunked, identity, trailers

For now I need a little meditation on HTTP RFC ;)

Tuesday, November 14, 2006

CORBA vs RMI

Interesting thing... There are a lot of technologies for distributed computing : CORBA, RMI, EJB, etc. What is the best choice for particular case ? Which are criterias to determine appropriate technology in some case ? To figure out criteria we need to answer some of the questions listed nere.

Do we need to integrate some applications written in different languages across enteprise ?
Do we'll switch to another technology in the future ? Can we feel more comfortable when can send Java objects as parameters to remote methods ? Is it politically correct to use proprietary protocol ? How much is the cost of CORBA/EJB/RMI developer and how the learning curve goes ? How the technologies supported by different vendors ?

And at least - performance. Some people say that invocation of remote CORBA method in comparison with RMI takes 3 times faster. I think it due using serialization... It will be fun to make some benchmarks in debug mode with YourKit debugger for example :)

Thursday, November 02, 2006

Using EJB 3.0 and Struts together

I have used Struts with ORM framework but I'm not sure how to properly
use it with EJB's. I have some stateless session beans which are
encapsulate business logic + some EJB 3.0 entities ("EJB 3.0 entities"
is more correct term than "Entity Beans" according to Mike Keith).
A book "Struts Kick Start" by James Turner and Kevin Bedell bring some
light on this topic.
"Chapter 18. Using Struts with Enterprise JavaBeans" - is nice
introduction and it doesn't matter that is non-EJB 3 related.

Wednesday, November 01, 2006

Install jBoss with EJB 3.0 support using command line

I'm using this command to install jBoss AS with EJB 3.0 support. It is rather more interesting than using GUI install steps :)

java -jar jboss-4.0.4.GA-Patch1-installer.jar -installGroup ejb3-clustered installpath=C:\server\jboss-4.0.4.GA

Change -installpath at your taste. -installGroup can be also ejb3.