Thursday, April 21, 2005

what we can learn from blogger's stack traces

For a few minutes just now, I was not able to log into Blogger because of an error in the web application. And the web app was generating this stack trace:

java.lang.RuntimeException: can't load class com.google.blogger.base.User from database
at com.google.blogger.dbreader.SqlServer.query(SqlServer.java:1639)
at com.google.blogger.base.BaseUser.select(BaseUser.java:116)
at com.google.blogger.base.BaseUser.selectByUserID(BaseUser.java:79)
at com.google.blogger.base.User.load(User.java:136)
at com.google.blogger.frontend.IdentityCookiePipe.decryptCookie(IdentityCookiePipe.java:181)
at com.google.blogger.frontend.IdentityCookiePipe.getUserByCookie(IdentityCookiePipe.java:219)
at com.google.blogger.frontend.IdentityCookiePipe.invoke(IdentityCookiePipe.java:116)
at com.google.servlet.pipe.ServletPipe.invokeNextPipe(ServletPipe.java:118)
at com.google.servlet.exceptionhandling.ExceptionHandlerPipe.invoke(ExceptionHandlerPipe.java:99)
at com.google.servlet.pipe.ServletPipe.invokeNextPipe(ServletPipe.java:118)
at com.google.servlet.pipe.LocaleContextPipe.invoke(LocaleContextPipe.java:116)
at com.google.servlet.BaseServlet.doGet(BaseServlet.java:89)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:261)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:360)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:604)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:562)
at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:679)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
at java.lang.Thread.run(Thread.java:534)
Caused by: java.sql.SQLException: [JTurbo 3.0.2 JDBC 2.1 Driver]: Communication Link Failure. Connection refused
at com.newatlanta.jturbo.driver.DataSource.getConnection(DataSource.java)
at com.newatlanta.jturbo.driver.DataSource.getConnection(DataSource.java)
at com.newatlanta.jturbo.driver.PoolManagerDataSource.b(PoolManagerDataSource.java)
at com.newatlanta.jturbo.driver.PoolManagerDataSource.a(PoolManagerDataSource.java)
at com.newatlanta.jturbo.driver.PoolManagerDataSource.getPooledConnection(PoolManagerDataSource.java)
at com.newatlanta.jturbo.driver.PoolManagerDataSource.getPooledConnection(PoolManagerDataSource.java)
at com.google.blogger.dbreader.SqlServer.getConnection(SqlServer.java:259)
at com.google.blogger.dbreader.SqlServer.query(SqlServer.java:1626)
... 46 more


This stack trace shows a couple of interesting things.

First, that all the "com.blogger" Java code has already been changed to "com.google" after only two years. This is lightning quick in the world of internal closed-source Java. A lot of companies never get around to doing that when they merge. Some of the Java code associated with Jrun is still "com.livesoftware", for instance.

Also, it shows that they are using Tomcat (version 4), but there are probably other ways to figure that out besides looking at stack traces.

Most interestingly, it shows that they are using Microsoft SQL server. Not Oracle, not MySql, not PostGres. They are using the stuff from Redmond. I know this for two reasons. One, the class name "com.google.blogger.dbreader.SqlServer". But that's Google class and they could have named it anything. The real giveaway is "com.newatlanta.jturbo". JTurbo is a product whose only reason for existence is to be a better JDBC driver for MS-SQL than Microsoft themselves can provide. I know because I use it at work. I wonder if this is a legacy from Blogger's roots, or if Google use MS-SQL for other stuff too?

Finally, it shows that they did not bother to do some steps that they could have done to prevent me from seeing this information!

Comments: