Wednesday, October 03, 2007

Programming Can Ruin Your Life

There are many essays and articles extolling the virtues of becoming a great programmer. You’ll have a sharp mind, great abstract reasoning skills, and a chance to become wealthy by working mere hours a day. This is what you’ve heard, right?

Sadly, no one ever tells you about the ways in which it will adversely affect your life. The physical effects are obvious. You’ll spend most of your time sitting, probably in an uncomfortable chair that doesn’t promote good posture. You’ll fuel yourself with food that is readily available, meaning it’s more than likely processed and full of sugar and you’ll likely choose either coffee or soda to stave off the drowsiness. A coworker once remarked, “If it doesn’t come out of a vending machine, programmers don’t eat it.”

But I’m not particularly interested in the health risks, as I said, they’re obvious. So what am I talking about? Programming changes more than your body. Programming changes the way you think. You might hear a programmer say, “I like python because it matches the way I think.” Or is it really that they’ve learned to think in python? Regardless of the language employed, you think differently when you program. No decent programmer will deny that. This is why it’s often so hard to explain to someone “how you do that” because, as clear as your explanation may be, you simply think differently. It is this change in thinking that can ruin your life.

The application of programming specific processes and habits to the everyday is where peril lies. The same traits that make you a great programmer can make you an awkward, misunderstood and miserable human being.

Programming presents you with a problem and allows you to eventually solve it provided you don’t quit. A solution is out there somewhere. Make enough attempts and chances are you’ll eventually prevail. Aren’t computers great? They afford a large degree of freedom in problem solving. If nothing else, you are able to make as may attempts as you please and it will happily execute each one. This instills in you a sense that failure is not final. Any obstacle can be hurdled. This is not true in the real world. While you may find second chances now and again, the wheels that turn in the big blue room are largely unforgiving. Time marches on in one direction.

When faced with an interesting programming problem your mind will chew it over in the background. Maybe it’s an algorithm you need to develop, maybe it’s a tricky architecture problem, maybe it’s data that needs to be modeled. It doesn’t matter. Your mind will quietly work the problem over in search of a solution. The “ah-ha!” moment will come when you’re in the shower, or playing Tetris. This practice of constant churning will slowly work its way into the rest of your life. Each problem or puzzle you encounter will start it’s own thread; the toughest and most troubling of which will be blocking.

A program is highly malleable. You can make a nearly unlimited number of changes. You can re-implement. You can optimize. You can run the compile-test-debug cycle ad infinitum. Make a change, see a result. Life is not like this. Every action you take is followed by a commit and the transaction cannot be rolled back. You can continue to make changes and optimizations as you move forward but the effects of these will not be immediately apparent. The instant feedback of development is sorely lacking in real life. Furthermore, your changes might simply be ignored. Data will be skipped. Blocks will not be executed. Optimizations will go unnoticed. The world is resistant to your tinkering.

Programmers become obsessed with perfection. This is why they are constantly talking about rewrites. They cannot resist optimum solutions. Perfection requires tossing aside mediocre ideas in search of great ones. A good programmer would rather leave a problem temporarily unsolved than solve it poorly. A good solution takes into account all predictable outcomes and solves the largest number of them in the most efficient way. This mindset prevents you from writing code with limited utility and life span. While it’s a wonderful trait to have in programming, the demons of scope and efficiency will start to assert themselves on your ordinary life. You will avoid taking care of simple things because the solution is inelegant or simply feels wrong. Time to think will no doubt yield a better result, you’ll say.

The obsession with perfection develops a forward-thinking mindset. The ability to anticipate provides a huge advantage because you won’t waist your time implementing solutions that ultimately fail due to short-sightedness or lack of imagination. You will constantly be mapping out flows and running the permutations through your head. Back in the real world, you will find yourself piecing together plans of breath-taking size and beauty that simultaneously resolve multiple problems and fulfill numerous dreams. You will attempt to kill every bird with one stone. The impossibility of actualizing these plans will be agonizing, yet your mind will continue to pour over every detail as it seeks to anticipate every possible outcome and construct the perfect solution.

Everything is now data. Every bit is worthy of attention. Every interaction is worthy of analysis. Your mind has been trained to do this since it is usually the insignificant or subtle bits that have to be rooted out when debugging. You will find it frustrating that everyone else does not collect and analyze data. You will notice details that others simply gloss over. Your penchant for detail and over-analysis will earn you strange glances and confused shrugs. Your decision making process will resemble that of your peers less and less.

The frantic pace of the software world will instill in you a sense of panic and urgency. You must do everything now. Tomorrow is too late. The thought of working constantly will no longer seem foreign or ridiculous. You will spend your free time feeling guilty about not working. But you will be working. Your hands may not be at the keyboard, but your mind will be.

The romanticized story of young upstarts toiling away in a garage to build the world’s next great company is alluring. It’s easy to convince yourself that the dream is there for the taking. But understand that there are many factors you cannot control. Luck and timing being but two. Don’t miss the life you have in the search for the one you think you want. To quote John Lennon, “Life is what happens while you are busy making other plans.” But perhaps Pascal said it best, “We never keep to the present. We … anticipate the future as if we found it too slow in coming and were trying to hurry it up, or we recall the past as if to stay its too rapid flight. We are so unwise that we wander about in times that do not belong to us and do not think of the only one that does; so vain that we dream of times that are not and blindly flee the only one that is… [We] think of how we are going to arrange things over which we have no control for a time we can never be sure of reaching… Thus we never actually live, but hope to live, and since we are always planning how to be happy, it is inevitable that we should never be so.”

Is programming the road to ruin? Or is it that those with a predilection for detail and mental gymnastics find themselves drawn to it. Perhaps it simply exacerbates a pre-existing mindset. There are certainly other traits (stereotypical or not) that most programmers seem to share. I have focused mainly on the negative impacts, but there are certainly positive ones as well. All things listed as bad can be good if simply kept in check. Obsession is dangerous, and anything great requires obsession. Programming is no exception.

http://devizen.com/blog/2007/09/11/ruin/

Single Sign On

In the last few weeks I was asked to help to integrate a set of built-in-house web applications with a Single Sign On (SSO) solution. After working with people from different teams, I realized that it would be a good idea to write a brief description of how the SSO solutions work in general. Perhaps this might help you to get started if you have to do something like this at some point.

SSO is by no means a new technology. It has been in use for a long time. Even before the Web Applications were available.

The most primitive of SSO systems is a piece of paper per user with a small table listing systems with the user names and passwords. This list can be generally stamped on the user monitor. Later on it can evolve, instead any simple piece of paper, it can be a post-it.

passwords.jpg
(for those of you interested in how I created this picture, I did it using the napkin look and feel)

Yes, you might be thinking that I am kidding here. And to some extent I am. However, this has been a big concern in the corporate world. That's the way it used to be, not by design, and it still is in some companies. Lots of applications, managed by different teams in the famous "silos", not integrated, each requiring the user to authenticate with its own username/password... you know the picture.

I think that that's how the need of SSO got started.

Early SSO systems worked as the post-it that the users where sticking to their monitors.

They were repositories of users/passwords pairs protected by a password. In that way before the user would authenticate to the destination system, they would first access the SSO repository, fetch their passwords, and continue authenticating with the system they were intending to work on the first place.

Lately, In a web based environment, this can be extremely simplified with a well know device: cookies.

Example

We will go over an SSO implementation with an example. Let's have 3 major components: The SSO server, Application A, Application B.

Here is how the system would work:

1) The user tries to access the application A.

2) Application A realizes that the user has not been authenticated. (See "user has been authenticated" for details).

3) Application A sends an HTTP redirect to the SSO server.

4) The SSO server sees that the user is not authenticated (again, See "user has been authenticated" for details).

5) The SSO server requires the user to authenticate.

6) The user submits username/password

7) SSO Server validates username/password. If they are valid, the user is "granted permission".

8) The user is redirected to Application A.

9) Application A sees that the user has been authenticated, and proceeds.

Granting permission:

When the username and password are validated by the SSO server, a unique large token is generated for the user. The token is going to have a unique identifier for the user's session. The SSO server keeps a list of the tokens associated with the credentials of the user that owns it. This token is set by the SSO server in the user's browser as a cookie.

User has been authenticated:

For an application to validate that a user has been authenticated it has to follow this steps:

1) Check for the token in the cookies.

2) Query the SSO server for the credentials associated with the token. If the token is valid, the SSO returns the credentials of the user for the application to continue. If the token is not present, or is invalid, the application knows that the user has not been authenticated, and is redirected to the SSO server.

This makes it look like there is a lot of work to get this type of setup. Luckily, it is not complicated at all. Most SSO servers come with a plug-in that is installed in the application/web server that intercepts all the requests, and performs the logic just described. Any application deployed in such a server will automatically get the user credentials, populated by the plug-in, just as if the user was authenticated locally using the JAAS framework.

A Note on Cookies

As most of you know the capabilities of setting and reading cookies are restricted by the domains. A web server that does not belong to the domain where the cookie was set will not be able to read the cookie.

For that reason the applications and the SSO server have to belong to the same domain. Indeed, if they are not to be part of the same domain the cookies would not work. For that case the URL rewriting technique can be used.

Development TIP:

When you are developing your app, no need to authenticate with the SSO. Just have each developer to work with a simple JAAS authentication within a local flat file (most of the IDEs have this by default). Get them to complete the development, and when you are ready to test, deploy it in your testing environment using the SSO plugin.

Napkin Look and Feel

  1. Latest
  2. Overview
  3. Development
  4. Sightings
  5. Acknowledgments
SourceForge.net Logo
java.net Member

Latest

New Wiki

Our Wiki gives you a place to share ideas and advice with other folks. We've started it off with some instructions about how to get Java applications to use Napkin for their Look and Feel.

Latest Release: 1.0, 18 March, 2006

  • Upgrade to Java 1.5.
      Several bugs vanished with this upgrade, but it does mean that this will not work anymore with earlier Java versions. So far it has seemed too much work to maintain a system that can work on both.
  • Sketched icons added
      Peter Goodspeed and Justin Crafford created a cool package to take an XML description of an icon and randomly perturb it around. This lets us easily have icons for dialog boxes, for example, that look sketched and slightly different each time. This is in the subpackage net.sourceforge.napkinlaf.sketch, and you can use it for diagrams as well. It's really, really cool.
  • Works on Windows
      Alex Lam took an interest in using Napkin as his default look & feel for NetBeans. Rather than refer him to an appropriate mental health professional, I put him on the team. He has fixed many, many issues, most specific to the Windows platform but including several other issues related to borders, opacity, and created a tileable sticky-note background for popups, etc. Welcome to the monkey house, Alex.
Note that these simple bullet items are each damn big. There were also, of course, lots of small fixes and tweaks to clean things up for the Big Release.

Overview

The Napkin Look & Feel is a pluggable Java look and feel that looks like it was scrawled on a napkin. You can use it to make provisional work actually look provisional, or just for fun.

The idea is to try to develop a look and feel that can be used in Java applications that looks informal and provisional, yet be fully functional for development. Often when people see a GUI mock-up, or a complete GUI without full functionality, they assume that the code behind it is working. While this can be used to sleazy advantage, it can also convince people who ought to know better (like your managers) that you are already done when you have just barely begun, or when only parts are complete. No matter how much you speak to their rational side, the emotional response still says "Done!". Which after a while leads to a later question: "That was done months ago! What are they doing? Playing Quake?" A good article on this is Joel on Software's “The Iceberg Secret, Revealed”.

So the idea is to create a complete look and feel that can be used while the thing is not done which will convey an emotional message to match the rational one. As pieces of the work are done, the GUI for those pieces can be switched to use the "formal" (final) look and feel, allowing someone looking at demos over time to see the progress of the entire system reflected in the expression of the GUI.

Over time, several folks have just liked the thing and wanted to use it for non-provisional GUI's. Sometimes this is because the application itself seems to match the theme, such as a brainstorming tool. And sometimes it's just that it looks fun.

This is all done using the Java Swing pluggable Look & Feel framework.

Sightings

Don't make the Demo look Done, from Kathy Sierra's blog Creating Passionate Users.
"Finally, it's great to know that there are tools to help make the look match the state, with my favorite being the Napkin Look and Feel, a GUI "skin" for Java that makes the interface look -- quite literally -- like it was scrawled on a napkin."
Matt Stephens' “Agile Development with ICONIX Process
"... if the working prototype was presented looking like a user interface mockup that had been scrawled on theback of a napkin, then the customer would be more likely to see it for what it actually is: a slightly working but mostly non-functional prototype... Seems like a great idea to us!" (You can read the pages here)
NetBeans Look & Feel Competition
Claudio Miranda submitted an entry with NapkinLAF on GTK.
Kirill Grouchnikov's blog
Compares various LAFs for their Right-to-Left menu alignment issues. Thanks to Kirill for reporting the issues ;-)
BlogEd
"I have added the napkin L&F to BlogEd and made it the default when run from cvs using 'ant run'. We can easily change it back if it gets in the way. The only bug I have noticed currently is that the pulling on the scrollbar seems to move the whole window. Perhaps Ken Arnold will know what the problem is there."
Daniel Steinberg's blog at java.net, April 5, 2004
A very nice & quick writeup.
Front page note on javadesktop.org , April 1 2004
Just a brief note pointing to the home page, but we got some good mail from it.

Acknowledgments

Peter Goodspeed and Justin Crafford created the sketching subsystem, as a senior project for their degrees at Worcester Polytechnic Institute. They did a great job, and solved an important problem. And thanks to Scott Anderson, a fellow student and friend of mine who suggested they get in touch with me to look for a thesis project.

Scott Violet of Sun has helped me pick apart some of the more abstruse and arcane bits of the plaf framework, which is full of 'em. Thanks a bunch, Scott, and thanks to Hans Muller, also of Sun, for plugging me together with him.

Brandon Franklin has contributed many spare cycles (of which he has none) to planning the upgrade to 1.5, making the whole process much easier.

The font "Felt Tip Roman" was created by Mark Simonson, who spent a lot of time with me on how to license this. He has kindly decided that this particular use does not require individual licensing for each user of the LAF, but can be done by special arrangement. The legalities are below, but beyond those legalities, we'd like to ask you all to be cool — if you like the font and want to use it, buy it properly. Making fonts is not easy, and font folks get their work ripped off far too often. If you do want to use it, buy it from his site http://www.ms-studio.com/, where he gets more from it.

The font "Ænigma Scrawl" was created by Brian Kent, and has worked very well for a handwritten font that scales reasonably to GUI-control sizes (most handwritten-style fonts are display fonts that only work in large sizes). To make things work better, Brian has adapted the font to adjust the spacing around some punctuation as well as some other tweaks. So the version released here is a custom one direct from the artist (which we believe he expects to roll back into the font at future date). We would like to thank Brian a lot for his quick and nimble cooperation, which made this work a lot better and easier on me.

Miro Jurišić has been very helpful in thinking through with me (sometimes for me) some of the hairy graphics problems. This definitely pushes into some poorly documented areas of the 2D API, and it has helped a lot to have someone to talk it through with. Thanks, Miro!

Brian Hawthorne created a quick and excellent selection of blueprint backgrounds for me to choose from. Thanks!

Several people have helped with testing, reporting bugs, and suggesting things. The most persistent have been: Deryl Steinert, Bob Herrmann, David Matuszek, Graham Perks, Henry Story, and Tom Eugelink. Thanks to all, and we'll be happy to have you be added to this list.

Essential firefox add-ons for web programmers

  • FireFTP - is a free, secure, cross-platform FTP client for Mozilla Firefox which provides easy and intuitive access to FTP servers, FireFTP includes more advanced features such as: directory comparison, syncing directories while navigating, SSL encryption, search/filtering, integrity checks, remote editing, drag & drop, file hashing, and much more!
  • IE Tab - is a great tool for web developers, since you can easily see how your web page displayed in IE with just one click and then switch back to Firefox.
  • Firebug - integrates with Firefox to put a wealth of development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.
  • The Web Developer - adds a menu and a toolbar to the browser with various web developer tools.
  • HTML Validator - is a Mozilla extension that adds HTML validation inside Firefox and Mozilla. The number of errors of a HTML page is seen on the form of an icon in the status bar when browsing.
  • ColorZilla - you can get a color reading from any point in your browser, quickly adjust this color and paste it into another program. You can Zoom the page you are viewing and measure distances between any two points on the page. The built-in palette browser allows choosing colors from pre-defined color sets and saving the most used colors in custom palettes.
  • CSS Validator - is a Mozilla Firefox extension which Validates a page using the W3C CSS Validator. Adds an option to the right-click context menu and to the Tools menu to allow for easy validation of the CSS of the current page.
  • MeasureIt - draw a ruler across any webpage to check the width, height, or alignment of page elements in pixels.
  • View formatted source - displays formatted and color-coded source and optional CSS information for each element.
  • View Source Chart - draws a Color-Coded Chart of a Webpage's Source Code and displays Source in its Altered State After the DOM has been Manipulated by JavaScript.
  • Venkman - the code name for Mozilla's JavaScript Debugger, aims to provide a powerful JavaScript debugging environment for Mozilla based browsers namely Firefox, Netscape 7.x/9.x series, Seamonkey 1.x/2.x.
  • iWEBTOOL - Access over 30 Webmaster Tools for Free directly from your web browser
  • http://livehttpheaders.mozdev.org/
  • LinkChecker - check webpage links at a glance with simple color coding. Ditch those massive listings of bad links that provide no context and add LinkChecker to your arsenal of web development tools today.
  • Load Time Analyzer is an extension created by Google that displays the number of events that are processed by a certain website and how long it takes to load them all. The load time displayed will obviously be influenced by your Internet connection, nonetheless it can provide a good indicator of the site speed.
  • Quick Locale Switcher - Allows you to quickly change and apply a different locale (language) in your Mozilla application.
  • XHTML-MP - allows firefox to render HTML content with the mime-type of application/vnd.wap.xhtml+xml. For any developer working with mobile applications, this provides an alternative to using a device emulator.
  • Console² - let's you display errors filtered by type (Errors, Warnings, Messages), language (JavaScript, CSS, XML) and context (Chrome, Content). Furthermore it provides a simple search box (as seen in the History and Bookmarks sidebars), hiding of duplicates, sidebar optimizations, a customizable toolbar and some more accessibility improvements.

  • Page validator - validates a page using the W3C Markup Validation Service. Adds an option to the right-click context menu and to the Tools menu to allow for easy validation of the current page. Opens the results in a new tab. This is a simple extension that will work only for online pages.
  • xmldeveloper - helps XML developers with their programming efforts by supplying a central toolbar for everything XML.
  • The Total Validator - provides one-click validation. Once installed all you do is browse to the page you want to validate then click on the 'TV' icon in the browser status bar.
  • Modify Headers - allows the user to Add, Modify and Filter out HTTP request headers. See the help tab in the Modify Headers window for more information.
  • The XPather - is a simple extension that integrates both with the browser and its DOMInspector. Thus, is't very lightweight and cross-platform. It is valuable mainly as a web/XML-app development and hacking tool.
  • LiveHTTPHeaders - display http headers in real time while pages are being downloaded from the Internet
  • Font Finder - Get all CSS styles of selected text in Firefox

Top 10+ source code search engines

Programmers are coding and coding in somewhere for some purpose. I wonder how many lines of code is written in a minute on the world :) I guess thousands of lines. But most them are coding the same snippets of code again and again. I always used "Koders" not to reinvent america, means not to rewrite the codes someone else have already solved. There are plenty of code search engines out there to serve us (programmers) with the millions of lines of codes to fasten our job. Here is the most used ones i could found on the internet.

  • Koders.com - is the leading search engine for open source code. Our source code optimized search engine provides developers with an easy-to-use interface to search for source code examples and discover new open source projects which can be leveraged in their applications.



  • O'Really Labs Code Search - The database currently contains over 123,000 individual examples, composed of 2.6 million lines of code — all edited and ready to use.
  • Google /*Code Search*/ - is a free product from Google which debuted in Google Labs allowing web users to search for open-source code on the Internet. Features include the ability to search using operators. These are lang:, package:, license: and file:. The code available for searching is in various formats including tar.gz, .tar.bz2, .tar, and .zip, CVS and Subversion repositories as well as snippets from HTML pages such as Wikipedia itself.





  • Codase - is an innovative and unique search engine for source code. Codase offers the best search results than any other services available today in source code search space.
  • Krugle - is a search engine that allows programmers and other developers to search Open Source repositories in order to locate open source code, and quickly share the code with other programmers on the internet.

  • JExamples - provides the ability to search for Java projects. The examples extracted from open source search engine understands the semantics of Java, so the search yields more accurate results than a text search. The site also provides the ability to rate examples so the highest rated examples will be shown first.
  • JSourcery - Search open source Java APIs
  • Merobase - is a software search engine that allows developers to find, share and reuse software components from the Internet. The engine harvests software components from a large variety of sources, including Apache, SourceForge, and Java.net.
  • All The Code - is a source code search engine, presently for the Java language but with more languages being added soon. Unlike similar source code search engines, All The Code considers the relation between code and uses this to help judge the relevance.
  • http://csourcesearch.net/
  • EMC Dev Network - Searching 312,750 lines of code at EMC Developer Network. Powered by Kders.
  • Codefetch - Its mission is to connect programmers and authors so that programmers get the information they need, and the work of authors is supported and encouraged.
  • DevX's Sourcebank - is a directory of links to source code and script posted around the Web. Use the Search option to find terms within the source code. To cast the widest net, use the search with All Types selected. Or, you can browse through a subset of the code by categories (below). First, select a filter, such as C or Java, by clicking on one of the square buttons and then choose one of the categories (such as Mathematics) from within that filter.

Programming Handbooks and Cheatsheets

Cheat sheets are useful one page document which you should print out and post it on the wall from of your eyes. It helps you to learn the subject more quickly, and saves your time.

PHP

AJAX

CSS

Perl

.NET
Python

Javascript

Ruby on Rails

Java

JSP

Javascript

HTML

Unix

Linux

C

C++
C#

Django

SQL

Web Development
Others

Most popular free/open source IDEs and Editors

I'm getting acquainted with Wicket (which I blogged about here). In doing so, I encountered some problems and got a few responses from Wicket's mailing list. Someone suggested that I use Log4j to debug my issues, and so -- for the first time -- I used Log4j today. So here, as a reminder to myself and possibly of benefit to others, is what I did to use Log4j for debugging a Wicket application deployed over Tomcat from NetBeans IDE:

  1. Stop the running Tomcat instance. (In the IDE's Runtime window.)
  2. Download Commons Logging and copy the JAR to Tomcat's common/lib folder.
  3. Download Log4j and copy the JAR to Tomcat's common/lib folder.
  4. Create a log4j.properties file in Tomcat's common/classes folder. Make sure it contains the following line:
    log4j.logger.wicket.util.resource=DEBUG

    The above line is only for the resource package. To enable debugging for all the Wicket packages, use this instead:

    log4j.logger.wicket=DEBUG

    This is my log4j.properties file. Make sure that you change the log4j.appender.R.File property to point to logs/tomcat.log file in Tomcat's base directory (which is inside the NetBeans IDE user directory).

  5. Deploy the Wicket application. (In the IDE's Projects window.)
  6. Go to the logs/tomcat.log file in Tomcat's base directory and, if errors have been picked up, note that there are lines such as the following:
    2005-07-02 20:41:25,140 [http-8084-Processor23]
    DEBUG wicket.util.resource.locator.ResourceStreamLocator -
    Attempting to locate resource 'wicket/examples/navomatic/Page1.html'
    on path [folders = [\], webapppaths: []]

Finally, I've found this document to be very helpful in setting up Log4j for Tomcat: Logging for Apache Tomcat and Velocity using Log4j

Log4j, Wicket, Tomcat, and NetBeans IDE

I'm getting acquainted with Wicket (which I blogged about here). In doing so, I encountered some problems and got a few responses from Wicket's mailing list. Someone suggested that I use Log4j to debug my issues, and so -- for the first time -- I used Log4j today. So here, as a reminder to myself and possibly of benefit to others, is what I did to use Log4j for debugging a Wicket application deployed over Tomcat from NetBeans IDE:

  1. Stop the running Tomcat instance. (In the IDE's Runtime window.)
  2. Download Commons Logging and copy the JAR to Tomcat's common/lib folder.
  3. Download Log4j and copy the JAR to Tomcat's common/lib folder.
  4. Create a log4j.properties file in Tomcat's common/classes folder. Make sure it contains the following line:
    log4j.logger.wicket.util.resource=DEBUG

    The above line is only for the resource package. To enable debugging for all the Wicket packages, use this instead:

    log4j.logger.wicket=DEBUG

    This is my log4j.properties file. Make sure that you change the log4j.appender.R.File property to point to logs/tomcat.log file in Tomcat's base directory (which is inside the NetBeans IDE user directory).

  5. Deploy the Wicket application. (In the IDE's Projects window.)
  6. Go to the logs/tomcat.log file in Tomcat's base directory and, if errors have been picked up, note that there are lines such as the following:
    2005-07-02 20:41:25,140 [http-8084-Processor23]
    DEBUG wicket.util.resource.locator.ResourceStreamLocator -
    Attempting to locate resource 'wicket/examples/navomatic/Page1.html'
    on path [folders = [\], webapppaths: []]

Finally, I've found this document to be very helpful in setting up Log4j for Tomcat: Logging for Apache Tomcat and Velocity using Log4j