OYC PSYC 110

open yale logo

I’ve stumbled upon a new means of relaxation at Open Yale Courses. It sounds strange that recordings of university lectures are relaxing but I find they are. Paul Bloom’s PSYC 110: Introduction to Psychology is far more interesting than television. I’m currently on lecture ten of twenty.

His has an enjoyable speaking style; the hour flies by. A sidebar at the end of Dr. Bloom’s lecture on Freud exemplifies his sense of humor.

“One other thing on Freud–just a story of the falsification of Freud. I was taking my younger child home from a play date on Sunday and he asked me out of the blue, “Why can’t you marry your mother or your father?” Now, that’s actually a difficult question to ask–to answer for a child, but I tried my best to give him an answer. And then I said–then I thought back on the Freud lecture and so I asked him, “If you could marry anybody you want, who would it be?” imagining he’d make explicit the Oedipal complex and name his mother. Instead, he paused for a moment and said, ‘I would marry a donkey and a big bag of peanuts.’ [laughter] Both his parents are psychologists and he hates these questions and at times he just screws around with us.” [source]

The lectures are available on the Open Yale Courses website as audio, video and text transcripts. There are reading assignments, which I skip. (I’m currently taking courses elsewhere with considerable reading requirements.) One could probably get most of the value found in the original course if they completed the assignments but that’s not really my objective. For me, the lectures are firstly informative and secondly entertaining.

I originally downloaded the audio files from iTunes U but found that I had to move the audio out of iTunes U and into music so I could create a playlists. The lectures show up out of order in iTunes U and I cannot for the life of me puzzle out how to rearrange the order except as a playlist.

It’s nice to find a gem among the dredge that we know as the internet.

Get Spiked

spiked e-zine logo

I’ve become increasingly disillusioned with broadcast and cable news outlets. News outlets have sadly taken distinctly partisan roles in society. I find their content specious at best and makes for very poor commentary. (One notable except is Deutsche Welle.)

I recently stumbled upon spiked, which itself has a bias but its bias pleasantly lacks the shrill insanity commonly found nowadays. It’s not news but rather commentary on newsworthy events and trends. Even those articles with which I disagree will often have a point two I hadn’t considered. I find this to be the real value.

spiked is an independent online phenomenon dedicated to raising the horizons of humanity by waging a culture war of words against misanthropy, priggishness, prejudice, luddism, illiberalism and irrationalism in all their ancient and modern forms. spiked is endorsed by free-thinkers such as John Stuart Mill and Karl Marx, and hated by the narrow-minded such as Torquemada and Stalin. Or it would be, if they were lucky enough to be around to read it.” —From the spiked about page, www.spiked-online.com

bash uuid generator

Onliner bash scripts are handy but bash and common utilities don’t always work the same on the two systems I most use: Centos vs. OS X.

centos $ cat /etc/redhat-release 
CentOS release 5.4 (Final)
osx $ sw_vers | head -n2
ProductName:	Mac OS X
ProductVersion:	10.6.2

For example, I recently wrote a simple script to generate a set of UUID using the uuidgen utility. OS X and Centos versions of uuidgen take very different parameters.

Of course they do.

Centos uuid manpage

UUIDGEN(1)                                                 UUIDGEN(1)

NAME
       uuidgen - command-line utility to create a new UUID value

SYNOPSIS
       uuidgen [ -r | -t ]
  ...

I like to use the uuidgen -r option to explicitly generate a random-based UUID. It’s not strictly necessary as this is the default behavior. Still, I like to put it in. That’s just me. OS X doesn’t have this option. Oh, well.

OS X uuidgen manpage

UUIDGEN(1)           BSD General Commands Manual           UUIDGEN(1)

NAME
     uuidgen -- generates new UUID strings

SYNOPSIS
     uuidgen [-hdr]
  ...

Next up, OS X generates UUID in upper case whereas Centos generates UUID in lower case.

centos $ uuidgen
18722f8e-14cd-41fb-a63e-af9ff1c287ce
osx $ uuidgen
81AE9EAC-0B8B-4DB9-B262-76AA8C285DD6

Again, not really a big deal but I like consistency. Easy to fix with a pipe and tr.

osx $ uuidgen | tr [:upper:] [:lower:]
62a4d6b9-e0a9-4996-9e71-e7291158b700

But I needed a set of UUID. A simple loop would suffice.

centos $ for i in `seq 1 4`; do uuidgen | tr [:upper:] [:lower:]; done
408bf1d7-80a6-41ee-8a75-f7bbb5b65dd7
ae5e0aa4-f0b2-48ff-9cfe-ab99fb37b5c7
7e0a7e69-364d-4259-9b3f-83d448e9b591
e1d1b257-974e-4754-a6d3-fe4566b55c93
osx $ for i in `seq 1 4`; do uuidgen | tr [:upper:] [:lower:]; done
-bash: seq: command not found

Drat! No `seq 1 4` in OS X.

Okay. Use the alternate form to declare a sequence.

osx $ for i in {1..4}; do uuidgen | tr [:upper:] [:lower:]; done
c861326b-bde8-4198-b45a-6bfb7016addb
ef813568-5d3d-4587-a170-8aab798fd83b
21fe8562-1511-4fd4-bd37-71b43c32e013
acb10051-9af8-42b8-9ac9-54010ad71d07

and verifiy that it also works on Centos.

centos $ for i in {1..4}; do uuidgen | tr [:upper:] [:lower:]; done
93c68aba-cbe5-4b79-a1cc-e00eaae0527a
c564a4f4-9d39-4d2d-8762-4ba506c97de8
f694000b-d2cc-4b31-aabd-c3facd13b081
86466e00-3948-45f7-9090-09ab816b8fb6

Would ruby be easier? Probably not for this simple hack.

If I knew ruby better, dropping into irb would be just as easy as bash oneliners. But there would be other problems. For example, “Which ruby?”

centos $ ruby -v
ruby 1.9.1p376 (2009-12-07 revision 26041) [x86_64-linux]
osx $ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]

tomcat error: clearThreadLocalMap

I’m trying to move from Tomcat 5.5.28 to Tomcat 6.0.26 for my Struts2-based webapp. I previously tried–unsuccessfully–to make the move to Tomcat 6.0.20 but had to roll back. There were problems with the underlying connection to mail that I didn’t have time to track down.

I use a standard stack.

$ cat /etc/redhat-release
CentOS release 5.4 (Final)

$ /usr/sbin/httpd -v
Server version: Apache/2.2.3
Server built:   Nov 12 2009 18:43:41

$ java -version
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

$ ls -l /usr/local | grep tomcat
… tomcat -> ./src/apache-tomcat-6.0.26

Be forewarned: I’m jotting down my notes and this seems to be the easiest place for me to find them later. If you find something unclear or missing, leave a comment and I will look into it.

I habitually edit and format log data to cut down on the noise and improve readability. This torques the purists. I’m not a purist. I won’t change the essentials but I will eliminate—what I consider to be—unimportant details. For example, I will replace unimportant date stamps

Mar 11, 2010 4:30:33 PM

with a marker that’s less distracting

$TIME

I also will wrap output so it will fit nicely in my blog. When I wrap, I will use the marker “↩”.

As an example, the $CATALINA_HOME/logs/catalina.out log entry produced upon startup:

$TIME org.apache.catalina.core.AprLifecycleListener init
INFO: Loaded APR based Apache Tomcat Native library 1.1.20.

$TIME org.apache.catalina.core.AprLifecycleListener init
INFO: APR capabilities: IPv6 [true], sendfile [true],↩
accept filters [false], random [true].

$TIME org.apache.coyote.ajp.AjpAprProtocol init
INFO: Initializing Coyote AJP/1.3 on ajp-8009

$TIME org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 544 ms

$TIME org.apache.catalina.core.StandardService start
INFO: Starting service Catalina

$TIME org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.26

$TIME org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor host-manager.xml

$TIME org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor manager.xml

$TIME org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ws

$TIME org.apache.coyote.ajp.AjpAprProtocol start
INFO: Starting Coyote AJP/1.3 on ajp-8009

$TIME org.apache.catalina.startup.Catalina start
INFO: Server startup in 2131 ms

So far, so good.

You can see from the startup entry that I am using the Tomcat Native Library. There is a nice section in Tomcat: The Definitive Guide that explains why not to use the native library but I use it anyway.

You’ll also notice that I don’t listen on port 8080; Tomcat connects only to Apache httpd via mod_jk.

#  grep -E "8[0-9]{3}" /usr/local/tomcat/conf/server.xml
<Server port="8005" shutdown="SHUTDOWN">
port="8009" 

# cat /etc/httpd/conf/workers.properties
workers.tomcat_home=/usr/local/tomcat
workers.java_home=/usr/java/default
ps=/

worker.list=router

worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

worker.worker1.redirect=worker2

worker.worker2.port=8009
worker.worker2.host=localhost
worker.worker2.type=ajp13
worker.worker2.lbfactor=1

worker.worker2.activation=disabled

worker.router.type=lb
worker.router.balance_workers=worker1,worker2

Everything else is pretty standard.

When I go to shut down, Tomcat 6.0.26 gives me a few surprise errors.

$TIME org.apache.coyote.ajp.AjpAprProtocol pause
INFO: Pausing Coyote AJP/1.3 on ajp-8009

$TIME org.apache.catalina.core.StandardService stop
INFO: Stopping service Catalina

$TIME org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: A web application created a ThreadLocal↩
  with key of type [null]↩
  (value [com.opensymphony.xwork2.inject.ContainerImpl$10@5a9b8ff9])↩
  and a value of type [java.lang.Object[]]↩
  (value [[Ljava.lang.Object;@1b0952e8])↩
  but failed to remove it when the web application was stopped.↩
  To prevent a memory leak, the ThreadLocal has been forcibly removed.

$TIME org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: A web application created a ThreadLocal↩
  with key of type [null]↩
  (value [com.opensymphony.xwork2.inject.ContainerImpl$10@1220b36])↩
  and a value of type [java.lang.Object[]]↩
  (value [[Ljava.lang.Object;@620e06ce])↩
  but failed to remove it when the web application was stopped.↩
  To prevent a memory leak, the ThreadLocal has been forcibly removed.

$TIME org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: A web application created a ThreadLocal↩
  with key of type [null]
  (value [com.opensymphony.xwork2.inject.ContainerImpl$10@1b1402c4])↩
  and a value of type [java.lang.Object[]]↩
  (value [[Ljava.lang.Object;@3ec19fbf])↩
  but failed to remove it when the web application was stopped.↩
  To prevent a memory leak, the ThreadLocal has been forcibly removed.

$TIME org.apache.coyote.ajp.AjpAprProtocol destroy
INFO: Stopping Coyote AJP/1.3 on ajp-8009

The question I have is, “Is this new or is the new listener included in the Tomcat 6 server.xml file reporting a previously missed problem?”

It turns out that Tomcat 6 has new listeners that detect this kind of problem.

The new Tomcat 6 adds a series of listeners to prevent against memory leaks and one of them, is against ThreadLocals.”

The new memory leak detection code in Tomcat has found an issue with an application that needs to be fixed.”

This seems to be a case of an existing problem which is just now being reported.

I should mention that I started tomcat and immediately shut it down. My webapp did not process any http requests between startup and shutdown. That doesn’t preclude my webapp from being the culprit, though.

I would be happier if Tomcat and/or Struts2 (Spring?) in a future release could eliminate the SEVERE notice. There’s something unsettling about ignoring serious warnings.

Can you hear me now?

package of original johnsonville brats

I ate too much last night. My wife had ‘girls night out’ which left me unsupervised as I made my dinner.

I powered through an entire package of Johnsonville Brats. Cause and effect… I was wide awake at 2AM, bloated as a poisoned pup. Uffda!

And, yes. It was worth it.

“What the hell”, says me? Good time to catch up on some random and completely unnecessary web browsing.

As it turns out, I learned something from Leo Babauta over on zenhabits.net. I had for years considered myself a minimalist. Whether other people agreed or not is irrelevant. It was my self-view. Leo brings up a good point, “[minimalism is] basically an extension of simplicity — not only do you take things from complex to simple, but you try to get rid of anything that’s unnecessary. All but the essential.”

It’s a nice distinction. I have some things that are unnecessary but I won’t jettison them until they becomes a nuisance. Not many things. Just some things. It’s more accurate to say, “I’m a practitioner of simplicity.”

Simplicity and minimalism are very closely related but not exactly the same. So, why split hairs? Because definitions are important. It’s how we see the world. Crisp, distinct definitions lead to a clear view of the world. Fuzzy definitions lead to a fuzzy view. Non-existent definitions lead to blind spots, things out there in the world that you simply cannot see.

I never thought about the importance of definitions much until 1995 when I read The Non-Designer’s Design Book by Robin Williams. Robin describes in chapter one—The Joshua Tree Epiphany—her experience on Christmas when she received a tree identification book. In this book was a description of a Joshua tree, a strange desert dwelling plant. She was sure she had never seen one until later that day. In the cul-de-sac where her parents lived were four houses with Joshua Trees in the front yard. Robin hadn’t seen her neighbors’ Joshua trees for thirteen years. Only when she had a definition—some way to distinguish Joshua trees from all other trees—was Robin able to see them.

Definitions allow us to distinguish between things and the distinctions bring _those_ things into view.

Distinctions matter. They affect one’s world view. But not all distinctions matter to all people. For some people, the difference between simplicity and minimalism may be irrelevant. Perhaps they are neither a practitioner of simplicity nor a minimalist and the difference between the two _is_ splitting hairs—in their world, in their experience. But in my world, in my experience, the difference _is_ important.

Connecting the dots. It behooves us to invest at least a modicum of interest on the definitions our friends and colleagues find important. It is the mutual set of distinctions which people hold that allows them to communicate with any degree of precision. Without a mutual set, it’s unlikely that any message will be heard. The words may be there but listener can’t hear them. Much like Robin couldn’t see the Joshua tree.

Apache Directory Indexing

Sometimes a problem persists long enough—is an irritant long enough—that I’ll burn an entire Sunday morning simply out of spite. Today’s irrational time-waste went to solving “Directory index forbidden by Options directive.”

[marmaduke ~] $ cat /var/log/httpd/error_log \
 | grep '\[error\]' \
 | head -1
[Sun Dec 06 09:25:05 2009] [error] [client 192.168.2.29]↩
Directory index forbidden by Options directive:↩
/var/www/documentation/public_html/

I have a development server that I use to offload work from my laptop.

[marmaduke ~] $ hostname
marmaduke

[marmaduke ~] $ cat /etc/redhat-release
CentOS release 5.4 (Final)

Among other things, marmaduke hosts scads of apache virtual hosts, including documentation. I’ve wanted to index the documentation directory for quite sometime but never could get apache configured to auto index.

Every configuration problem has already been solved by someone else. A quick search (apache+allow+directory+index) yielded surprisingly consistent instructions.

These instructions yielded consistent failure for me. I simply could not get auto indexing to work. Until now.

My apache installation is a basic yum install.

[marmaduke ~] $ yum list | grep httpd | grep installed
httpd.x86_64           2.2.3-31.el5.centos    installed
httpd-devel.x86_64     2.2.3-31.el5.centos    installed
httpd-manual.x86_64    2.2.3-31.el5.centos    installed

I’ve extracted (below) a partial listing of relevant parts from the httpd.conf file.

I include configuration files from two directories: module configurations in /etc/httpd/conf.d/ and all virtual host configurations in /etc/httd/conf.d/hosts/.

For the most part, I leave httpd.conf untouched. Note that apache runs under the user and group named ‘apache’.

# /etc/httpd/conf/httpd.conf (partial listing)
Listen 80

Include conf.d/*.conf
Include conf.d/hosts/*.conf

User apache
Group apache

ServerName marmaduke:80
UseCanonicalName Off

DocumentRoot "/var/www/html"

<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

DirectoryIndex index.html index.html.var

IndexOptions FancyIndexing VersionSort NameWidth=* HTMLTable

NameVirtualHost *:80

Permissions are important.

I place my documentation directories in /var/www/documentation/public_html and the entire tree from /var/www/documentation downwards has the same user and group name. All directories have 755 permission and all non-directories have 644 permission.

[marmaduke ~] $ ll /var/www
drwxr-xr-x 3 kelly apache 4096 Dec  6 09:23 documentation

[marmaduke ~] $ ll /var/www/documentation
drwxr-xr-x 7 kelly apache 4096 Dec  6 11:51 public_html

[marmaduke ~] $ ll /var/www/documentation/public_html
-rw-r--r-- 1 kelly apache 5174 Dec  6 09:33 favicon.ico
drwxr-xr-x 2 kelly apache 4096 Dec  6 09:21 icecast-2.3.2
drwxr-xr-x 3 kelly apache 4096 Dec  6 12:00 mysql-5.0
drwxr-xr-x 4 kelly apache 4096 Dec  6 11:50 mysql-5.1
drwxr-xr-x 3 kelly apache 4096 Dec  6 11:51 mysql-5.4
drwxr-xr-x 3 kelly apache 4096 Dec  6 11:51 mysql-5.5

[marmaduke ~] $ ll /var/www/documentation/public_html/mysql-5.0
drwxr-xr-x 3 kelly apache 4096 Dec  6 10:05 en

My virtual host enables indexing through the Directory directive. So far, this is consistent with most of the instructions found through web search. Yet, auto indexing still didn’t work for me.

# /etc/httpd/conf.d/hosts/documentation.conf
<VirtualHost *:80>
  DocumentRoot /var/www/documentation/public_html
  ServerName documentation.site
  Options Indexes FollowSymLinks

  <Directory "/var/www/documentation/public_html">
    Options Indexes FollowSymLinks
    Order allow,deny
    Allow from all
  </Directory>

  RewriteEngine on
  RewriteLogLevel 1
</VirtualHost>

It turns out that there is a nastly little surprise in one of the configuration files that comes standard with the centos yum install.

Inside LocationMatch, there the Options directive turns off Indexes. From the apache documentation, “Regardless of any access restrictions placed in <Directory> sections, the <Location> section will be evaluated last…

# /etc/httpd/conf.d/welcome.conf
<LocationMatch "^/+$">

  # this is the culprit!
  Options -Indexes

  ErrorDocument 403 /error/noindex.html
</LocationMatch>

Since LocationMatch is evaluated last, the -Indexes parameter disables options set in any Directory directive. Either changing the parameter -Indexes to Indexes or deleting the welcome.conf file will allow auto indexing (assuming the other configurations are correct).

screenshot of apache directory listing