Archive for May, 2012

Self-selecting for the thick-skinned means turning away contributors.

May 29, 2012

Every so often, usually in the middle of an online argument or flame war, someone will say that the climate of the group has him or her uncomfortable. He’ll say something like “I don’t want to be around all this hostility” or, worst of all, “This makes me not want to get involved.” The reply sometimes comes back “You’re just thin-skinned.”

Labeling someone as “thin-skinned” makes no sense. There is no measure of skin thickness. When someone says “You are thin-skinned,” he’s really saying “You are less willing to put up with anti-social behavior than I am.”

I wonder what the speaker hopes for “You’re just thin-skinned” to do. Is that supposed to inspire the listener? Make him realize the error of his ways? I don’t know what the intent is, but it communicates “You are wrong to feel that way” and that’s hurtful, not helpful. There’s nothing wrong with not wanting to put up with anti-social behavior.

None of this is an endorsement of being easily offended, however you may define “easily.” I wish we all had the attitude of Gina Trapani, who once said “I eat your sexist comments for breakfast. YUM.” But not everyone does, and that’s no reason to shut them out. Yes, online communities can get hostile, but that doesn’t mean we need to tacitly endorse that hostility. We can do better, and we should, to help our communities grow and thrive.

Aside from ignoring the aspect of treating other humans with compassion, it makes no sense to ignore or insult those you see as thin-skinned. Ricardo Signes recalled a lightning talk at OSCON 2011 where someone noted “When we say that this community requires a thick skin, it means we’re self-selecting for only people with thick skin.”

Self-selecting for the thick-skinned means turning away contributors. If you were running a restaurant, and a customer said “I like the food here, but my waiter was rude to me,” the sensible restaurateur would take this as an opportunity for improvement. You’d thank the patron for bringing it to your attention. You wouldn’t say “Well, that’s just the way it is here” or “You’re just too sensitive.” The wise restaurateur would see it as an opportunity for improvement.

There’s an adage in business that for every customer complaint you get, there are between ten to 100 other dissatisfied customers that don’t say anything and go somewhere else. This is especially so in the case of those tarred as “thin-skinned” by someone in the community. For every person who speaks up and says “I don’t like this hostility”, how many more unsubscribe from the list, leave the IRC channel or vow not to come back to the user group meeting again, all without saying a word about it?

In online communities, we’re not dealing with an owner-customer relationship, but nonetheless contributors to the community are a scarce commodity. A business owner can’t afford to turn away customers. Is your online community or open source project so flush with talent that you can turn away contributors?

Advertisements

My Solr+Tomcat troubles, and how I fixed them

May 22, 2012

I’ve been working at getting Solr working under Tomcat, and spent most of a day working on fixing these problems. The fixes didn’t take so much time as the trying to grok the Java app ecosystem.

My Solr install worked well. I was able to import records and search them through the interface. Where I ran into trouble was with the Velocity search browser that comes with Solr.

I’m documenting my troubles and their solutions here because otherwise they won’t exist on the web for people to find. Putting solutions to problems on the web makes them findable for the next poor guy who has the same problem. I figure that if I spend a day working on fixing problems, I can spend another hour publishing them so others can benefit.

These are for Solr 3.5 running under Tomcat 6.0.24.

Unable to open velocity.log

Velocity tries to create a file velocity.log and gets a permission failure.

HTTP Status 500 - org.apache.velocity.exception.VelocityException:
Failed to initialize an instance of
org.apache.velocity.runtime.log.Log4JLogChute with the current
runtime configuration. java.lang.RuntimeException:
org.apache.velocity.exception.VelocityException: Failed to initialize
an instance of org.apache.velocity.runtime.log.Log4JLogChute with
the current runtime configuration. at
...
Caused by: java.io.FileNotFoundException: velocity.log
(Permission denied) at java.io.FileOutputStream.openAppend(Native
Method) at java.io.FileOutputStream.<init>(FileOutputStream.java:207)
...

But where is it trying to create the file? What directory? Since
no pathname was specified, it seemed that the file would be created
in the current working directory of Tomcat. What would that be?

First I had to figure out what process that Tomcat was running as:

frisbee:~ $ ps aux | grep tomcat
tomcat     498  0.6  1.3 6240056 214880 ?      Sl   09:27   0:10 /usr/lib/jvm/java/bin/java ....

In this case, it’s PID 498. So we go to the /proc/498 directory and see what’s in there.

frisbee:~ $ cd /proc/498
frisbee:/proc/498 $ ls -al
ls: cannot read symbolic link cwd: Permission denied
ls: cannot read symbolic link root: Permission denied
ls: cannot read symbolic link exe: Permission denied
total 0
dr-xr-xr-x   7 tomcat tomcat 0 May 22 09:27 ./
dr-xr-xr-x 173 root   root   0 May 17 11:33 ../
dr-xr-xr-x   2 tomcat tomcat 0 May 22 09:58 attr/
-rw-r--r--   1 tomcat tomcat 0 May 22 09:58 autogroup
-r--------   1 tomcat tomcat 0 May 22 09:58 auxv
-r--r--r--   1 tomcat tomcat 0 May 22 09:58 cgroup
--w-------   1 tomcat tomcat 0 May 22 09:58 clear_refs
-r--r--r--   1 tomcat tomcat 0 May 22 09:56 cmdline
-rw-r--r--   1 tomcat tomcat 0 May 22 09:58 coredump_filter
-r--r--r--   1 tomcat tomcat 0 May 22 09:58 cpuset
lrwxrwxrwx   1 tomcat tomcat 0 May 22 09:58 cwd
...

We can see that cwd is a symlink to a directory, but we have to be root to see what the target directory is. I have to run ls again as root.

frisbee:/proc/498 $ sudo ls -al
[sudo] password for alester:
total 0
dr-xr-xr-x   7 tomcat tomcat 0 May 22 09:27 .
dr-xr-xr-x 174 root   root   0 May 17 11:33 ..
dr-xr-xr-x   2 tomcat tomcat 0 May 22 09:58 attr
-rw-r--r--   1 tomcat tomcat 0 May 22 09:58 autogroup
-r--------   1 tomcat tomcat 0 May 22 09:58 auxv
-r--r--r--   1 tomcat tomcat 0 May 22 09:58 cgroup
--w-------   1 tomcat tomcat 0 May 22 09:58 clear_refs
-r--r--r--   1 tomcat tomcat 0 May 22 09:56 cmdline
-rw-r--r--   1 tomcat tomcat 0 May 22 09:58 coredump_filter
-r--r--r--   1 tomcat tomcat 0 May 22 09:58 cpuset
lrwxrwxrwx   1 tomcat tomcat 0 May 22 09:58 cwd -> /usr/share/tomcat6

I could also have used the stat command.

frisbee:/proc/498 $ sudo stat cwd
File: `cwd' -> `/usr/share/tomcat6'
Size: 0               Blocks: 0          IO Block: 1024   symbolic link
Device: 3h/3d   Inode: 100017      Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (   91/  tomcat)   Gid: (   91/  tomcat)
Access: 2012-05-22 09:58:17.131009458 -0500
Modify: 2012-05-22 09:58:17.130009715 -0500
Change: 2012-05-22 09:58:17.130009715 -0500

So we find that the CWD is /usr/share/tomcat6. I don’t want the tomcat user to have rights to that directory, so instead I create a velocity.log file in a proper log directory and then symlink
to it.

frisbee:/proc/498 $ cd /var/log/tomcat6
frisbee:/var/log/tomcat6 $ sudo touch velocity.log
frisbee:/var/log/tomcat6 $ sudo chown tomcat:tomcat velocity.log
frisbee:/var/log/tomcat6 $ cd /usr/share/tomcat6
frisbee:/usr/share/tomcat6 $ sudo ln -s /var/log/tomcat6/velocity.log velocity.log

Now the app is able to open /usr/share/tomcat6/velocity.log without error.

log4j error

Once I created a log file Velocity could write to, it stared throwing an error with log4j. log4j is the Java logging package.

org.apache.log4j.Logger.setAdditivity(Z)V java.lang.NoSuchMethodError:
org.apache.log4j.Logger.setAdditivity(Z)V at
org.apache.velocity.runtime.log.Log4JLogChute.initAppender(Log4JLogChute.java:126) at
org.apache.velocity.runtime.log.Log4JLogChute.init(Log4JLogChute.java:85) at
org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:157) at
org.apache.velocity.runtime.log.LogManager.updateLog(LogManager.java:255) at
org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:795) at
org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:250) at
org.apache.velocity.app.VelocityEngine.init(VelocityEngine.java:107) at
org.apache.solr.response.VelocityResponseWriter.getEngine(VelocityResponseWriter.java:132) at
org.apache.solr.response.VelocityResponseWriter.write(VelocityResponseWriter.java:40) at
org.apache.solr.core.SolrCore$LazyQueryResponseWriterWrapper.write(SolrCore.java:1774) at
org.apache.solr.servlet.SolrDispatchFilter.writeResponse(SolrDispatchFilter.java:352) at
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:273) at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:555) at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857) at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:679)

In searching the web for this error, I found this ticket in the Solr bug tracker that says that the log4j .jar files should be removed from the Solr tarball, because they can conflict with existing .jars on the system. That conflict was exactly the error I was getting.

I wanted to remove the extra .jar files, so I used locate to search my system for any log4j .jars. Indeed, there was one installed with solr:

frisbee:~ $ locate log4j
...
/var/lib/tomcat6/webapps/solr/WEB-INF/lib/log4j-over-slf4j-1.6.1.jar
...

So I just changed the extension of the file so it wouldn’t get loaded as a .jar.

frisbee:~ $ sudo mv /var/lib/tomcat6/webapps/solr/WEB-INF/lib/log4j-over-slf4j-1.6.1.{jar,jarx}

Now Velocity loads beautifully. Now the real work starts: Configuration of Velocity to understand the schema in my Solr core.

I hope this helps someone in the future!

Rethink the post-interview thank you note

May 15, 2012

Good golly do people get riled up by the idea of sending a thank you note after a job interview. “Why should I thank them, they didn’t give me a gift!” is a common refrain in /r/jobs.  “They should be thanking me!”

I think the big problem is the name, “thank you note.”  It makes us recall being forced to say nice things about the horrible sweater Aunt Margaret gave us for Christmas.

It’s not a thank you note. It’s a followup. It doesn’t have to be any more than this:

Dear Mr. Manager,

Thank you for the opportunity to meet with you today. I enjoyed the interview and tour and discussing your database administration needs. Based on our discussions with Peter Programmer, I’m sure that my PostgreSQL database administration skills would be a valuable addition to the Yoyodyne team. I look forward to hearing from you.

Sincerely,
Susan Candidate.

There’s nothing odious there. You’re not fawning or begging. You’re thanking the interviewer for his time, reminding him of key parts of the interview and your key skills, and reasserting that you are interested in the job. (And before you say “Of course I’m interested, I went to the interview!”, know that perceived indifference and/or lack of enthusiasm is an interview killer.)

People ask “Do I really have to do that?” and I say “No, you don’t HAVE to, you GET to.” It’s not a chore, it’s an opportunity.

Please help me with terminology for “small acts that add to a greater whole”

May 11, 2012

I’m looking for a term to describe small positive actions that individuals do to add up to a greater whole.

Examples in the world of open source software might include:

  • Answering a question on a mailing list
  • Testing a beta release
  • Welcoming someone to a community
  • Submitting a bug report, or clarifying an existing one
  • Patching a bug
  • Closing a ticket
  • Removing dead code
  • Silencing a compiler warning
  • Adding a test to the test suite
  • Blogging about how you use a software package
  • Thanking others on the project
  • Patching the documentation
  • Adding a tutorial example to the docs
  • Adding notes to the README
  • Hosting or speaking at a user group meeting
  • Attending a user group meeting

Outside of software development specifically, the best example is making an edit to a Wikipedia page. Wikipedia is nothing but millions of these small actions, aggregated.

The term “microaggression” was coined to describe a small non-physical interaction between people that communicates hostility towards others.  I’m looking for the opposite.

The Japanese term “kaizen” means “improvement”, or “change for the better”, and is close to what I’m talking about, but I’m looking for a term for the actions, not the process.

If there’s not a similar term to describe the small positive actions that create a greater whole, I’m going to coin it.

Ideas? References? Existing terms I haven’t thought of?  Please post them below.