Skip to content

Google Projects?

Update, 9:57am: Well, I feel a bit foolish. Looks like Google is planning to host some open source projects.

Brian thinks the world needs google projects. Unlike Brian, I am not a committer on any open source project, but I do use a fair number. I also have believed in the principles of open source for years.

Does the world need yet another projects website? As I said above, I can’t speak for committers, but as a user of their work, I’d like the environment to be as productive as possible for them (how generous of me, no?).

But as a user, I can tell you that a real problem is just finding some of the great work that has already been done. As an example, Google and Yahoo had no idea that the CalendarTag library was out there, at least in the first 30 pages of results. Perhaps I was choosing poor keywords, but I had a tough time finding what I was looking for. Perhaps a microformat for open source software projects would help?

SourceForge has flaws, but the fact is that its search found what I was looking for, probably because SourceForge search is by nature limited to software projects. The fact that you have to go through three pages to download a tarball is an annoyance, but not a capital one. It’s overweighed by the fact that SF has a enormous number of projects (126,520, as of today) and is relatively fast.
Brian and I are approaching the problem of a new projects database from different perspectives, but I believe that one very real problem in management of open source projects is location of the appropriate project; search in other words. Sites like CMSMatrix are a start, but don’t work as well for smaller components. And adding Google Projects to the mix isn’t going to solve this problem.

[tags]Google, project management, SourceForge[/tags]

Moving to WordPress

Well, I finally decided to move to a more modern blogging platform. I have used Moveable Type 2.64 for almost three years, but it was time to move on:

* I had turned off comments because of blog spam. But I’ve recently heard from several folks that they’d wanted to comment. I love comments and the discussion that ensues, so I wanted a more sophisticated commenting workflow.

* I wanted easy support for tagging posts. How Web 2.0&#tm;!

* General cruft from a 3 year old program: MT is well designed and I have had few problems with it, but I wanted to see what the current state of blogging software was.

I don’t know whether I could have had such features with a more modern version of Movable Type, but it certainly seemed to me that WordPress has more mindshare, plus it’s open source. And it is supported by my ISP. So, I moved from Movable Type 2.64 to WordPress 2.0.2. I followed these fantastic directions. and, for importing my 350+ entries with correct permalinks, I followed these directions.

I ran into only a few problems.

* The directions on codex.wordpress.org appear to be for a slightly different version of wordpress and reference import-mt.php, rather than mt.php

* I ended up having to edit my php.ini file to up the memory to import my 1.5 meg MT export. 10M wasn’t enough, 50M was plenty.

* The directions for preserving your MT search engine entries are great, but I ran into one problem. Because I have an old version of Apache, this RewriteRule did not work:

RewriteRule archives/0*(\d+).html /uri/to/blog/index.php?p=$1

Instead, I had to use plain old character classes:

RewriteRule archives/0*([0123456789]+).html /uri/to/blog/index.php?p=$1

Her’s my entire RewriteEngine entry:

RewriteEngine on
RewriteRule weblog/archives/0*([0123456789]+).html wordpress/index.php?p=$1
RewriteRule weblog/index.rdf /wordpress/index.php?feed=rdf
RewriteRule weblog/index.rss /wordpress/index.php?feed=rss
RewriteRule weblog/index.xml /wordpress/index.php?feed=rss2
# http://www.mooreds.com/weblog/archives/2004_10.html to
# http://www.mooreds.com/wordpress/?m=200410

RewriteRule weblog/archives/([0123456789][0123456789][0123456789][0123456789])_([0123456789][0123456789]).html /wordpress/index.php?m=$1$2

# http://www.mooreds.com/weblog/archives/cat_books.html to 3
RewriteRule weblog/archives/cat_books.html /wordpress/index.php?cat=3
RewriteRule weblog/archives/cat_java.html /wordpress/index.php?cat=5
RewriteRule weblog/archives/cat_mobile_technology.html /wordpress/index.php?cat=7
RewriteRule weblog/archives/cat_programming.html /wordpress/index.php?cat=6
RewriteRule weblog/archives/cat_technology.html /wordpress/index.php?cat=4
RewriteRule weblog/archives/cat_technology_and_society.html /wordpress/index.php?cat=2
RewriteRule weblog/styles-site.css /wordpress/wp-content/themes/ocadia/style.css
RewriteRule weblog/ /wordpress/

* Users I imported, even if I gave them the Editor role, weren’t able to edit posts they owned. I may figure this out later, but right now I just made every user an admin.

So far I’ve been very happy with my decision, if for no other reason than the built-in comment moderation and the UI advances. Let’s see if WordPress lasts for three years.

[tags]wordpress, weblog migration, moveabletype,[/tags]

Notes from a talk about DiamondTouch

I went to another University of Colorado computer science colloquium last week, covering Selected HCI Research at MERL Technology Laboratory. I’ve blogged about some of the talks I’ve attended in the past.

This talk was largely about the DiamondTouch, but an overview of Mitsubishi Electronic Research Laboratories was also given. The DiamondTouch is essentially a tablet PC writ large–you interact through a touch screen. The biggest twist is that the touch screen can actually differentiate users, based on electrical impulses (you sit on special pads which, I believe, generate the needed electrical signatures). To see the DiamondTouch in action, check out this YouTube movie showing a user playing World Of Warcraft on a DiamondTouch. (For more on YouTube licensing, check out the latest Cringely column.)

What follows are my loosely edited notes from the talk by Kent Wittenburg and Kathy Ryall.

[notes]

First, from Kent Wittenburg, one of the directors of the lab:

MERL is a research lab. They don’t do pure research–each year they have a numeric goal of business impacts. Such impacts can be a standards contribution, a product, or a feature in a product. They are associated with Mitsubishi Electric (not the car company).

Five areas of focus:

  • Computer vision–2D/3D face detection, object tracking
  • Sensor and data–indoor networks, audio classification
  • Digital Communication–UWB, mesh networking, ZigBee
  • Digital Video–MPEG encoding, highlights detection, H.264. Interesting anecdote–realtime video processing is hard, but audio processing can be easier, so they used audio processing to find highlights (GOAL!!!!!!!!!!!!) in sporting videos. This technology is currently in a product distributed in Japan.
  • Off the Desktop technologies–touch, speech, multiple display calibration, font technologies (some included in Flash 8 ), spoken queries

The lab tends to have a range of time lines–37% long term, 47% medium and 16% short term. I think that “long term” is greater than 5 years, and “short term” is less than 2 years, but I’m not positive.

Next, from Kathy Ryall, who declared she was a software person, and was focusing on the DiamondTouch technology.

The DiamondTouch is multiple user, multi touch, and can distinguish users. You can touch with different fingers. The screen is debris tolerant–you can set things on it, or spill stuff on it and it continues to work. The DiamondTouch has legacy support, where hand gestures and pokes are interpreted as mouse clicks. The folks at MERL (and other places) are still working on interaction standards for the screen. The DiamondTouch has a richer interaction than the mouse, because you can use multi finger gestures and pen and finger (multi device) interaction. It’s a whole new user interface, especially when you consider that there are multiple users touching it at one time–it can be used as a shared communal space; you can pass documents around with hand gestures, etc.

It is a USB device that should just plug in and work. There are commercial developer kits available. These are available in C++, C, Java, Active X. There’s also a Flash library for creating rapid prototype applications. DiamondSpin is an open source java interface to some of the DiamondTouch capabilities. The folks at MERL are also involved right now in wrapping other APIs for the DiamondTouch.

There are two sizes of DiamondTouch–81 and 107 (I think those are the diagonal measurements). One of these tables costs around $10,000, so it seems limited to large companies and universities for a while. MERL is also working on DiamondSpace, which extends the DiamondTouch technology to walls, laptops, etc.

[end of notes]

It’s a fascinating technology–I’m not quite sure how I’d use it as a PC replacement, but I could see it (once the cost is more reasonable) but I could see it as a bulletin board replacement. Applications that might benefit from multiple user interaction and a larger screen (larger in size, but not in resolution, I believe), like drafting and gaming, would be natural for this technology too.

CalendarTag: A simple JSP Calendar Component

Update, 8/10/2006: There’s at least one other open source calendar generation taglib that looks like it’s worth a download (even though it’s older). That author hoped that code would make it into the Jakarta Taglibs but I didn’t find any evidence of that.

I was looking around at jsp calendar components for a client. I’d previously had a hard time finding a decent one, so I didn’t hold out much hope. Luckily, this search was slightly different–I don’t need any fancy features, just a simple calendar display rendered in html, with links on the day numbers. In addition, the calendar needs to be indexable, so FlatCalendarXP, which I’ve used before, is not an option.

I looked at the HtmlCalendarBean and the Calendar Taglib, both from ServletSuite. I expected the price to be reasonable, but didn’t expect source, which was important for the client.

A bit of digging around on SourceForge found the perfect project: CalendarTag. This project looks abandoned, but the author got things into good shape before ceasing development. I’d say the project is mature, rather than abandoned. In addition, he responded to my questions (including “is this project alive?”) in less than 24 hours.

I found the documentation to be very useful. In addition, you can customize the
calendar’s output to a very large degree. I especially like the decorator, which lets you control exactly how each day is displayed by implementing a relatively simple interface or extending a a class.

Make no mistake. This is a simple component which just displays a calendar in html. There’s no support for users or events (Update 3:24. I should have read the docs more closely and said, there’s no built in support for events or users. From within the calendar, you have access to the request and so can code up event handling and/or user specific calendars.). If you want those features, I’d look at a more complex calendaring system. Calendartag does something simple and does it well.

One tip–you’ll need to have the standard-1.0.4.jar file available to your web application, as well as the calendartag-1.0-rc4.jar file, otherwise you see this rather fearsome exception:

org.apache.jasper.JasperException: org/apache/taglibs/standard/tag/el/core/ExpressionUtil
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:254)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
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.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:2422)
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:163)
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:199)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:700)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:584)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:595)

root cause

javax.servlet.ServletException: org/apache/taglibs/standard/tag/el/core/ExpressionUtil
at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:536)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:59)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:210)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
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.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:2422)
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:163)
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:199)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:700)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:584)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:595)

Using wget to verify on the fly page compression

I’ve written about wget before, but I just found a very cool use for it. I’m looking at ways to speed up a site, by stripping out whitespace. I found one servlet filter by googling around. However, that code has a license restriction for commercial use (you just have to pay for it).

A bit more looking and I found this fantastic article: Two Servlet Filters Every Web Application Should Have. Give it a read if you do java web development. The article provides a free set of filters, one of which compresses a servlet response if the browser can handle it. (I’ve touched on using gzip for such purposes before as well.)

I was seeing some fantastic decreases in page size. (The article states that you can’t tell, but FireFox’s Page Info command [ Tools / Page Info ] seemed to reflect the differences.) Basically, a 300% decrease in size: 50K to 5K, 130K to 20K. Pretty cool. Note that if your application is CPU bound, adding this filter will not help performance. But if you’re bandwidth bound, decreasing your average page size will help.

I couldn’t believe those numbers. I also wanted to make sure that clients who didn’t understand gzip could still see the pages. Out comes trusty wget. wget url pulls down the standard sized file. wget --header="accept-encoding: gzip" url pulls down a gzipped version that I can even ungzip and verify that nothing has changed.

The only issue I saw was that ‘ c ‘ is apparently rendered as the copyright symbol in uncompressed pages. For compressed pages, you need to use the standard: ©. Other than that, the compression was transparent. Way cool.

GWT Mortgage Calculator Conclusion

This past week has been a whirlwind, including a whole lot of learning on my part and three releases of the Colorado HomeFinder site. Just to rehash, I’ve built three versions of the software:

In general, from a java developer perspective, this is my take on the strengths and weaknesses of GWT.

Strengths:

  • Can use normal java dev/debug environment–in particular, being able to set breakpoints in what will be javascript was useful
  • Hides javascript cross browser messiness
  • Allows rich uis to be built for web using same paradigms as other windowing toolkits (event listeners, layouts, panels, etc). As some folks have said, it is Swing for the web.
  • Ability to create widget libraries–using module ‘inheritance’ you can easily leverage other folk’s work. See this list for a collection of GWT widgets.

Weaknesses:

  • Build integration–I really don’t understand why they haven’t wrapped in an ant task, though others have done it for them, and there is an -ant switch on projectCreator.cmd which generates a stub build.xml
  • Documentation–again, I’ve found the Google Groups to be tremendous, while the Google provided documentation could use some brushing up.
  • Some cross browser weirdnesses–the only serious one I saw was IE not responding to click events on one page I built. This was due to a table of width 100% next to the div where the GWT widgets were dynamically creating DOM elements. But it only showed up on IE.
  • Any ui built by GWT is not indexable by search engines. This necessarily limits what you can do with it–you can build web applications but not web sites.