Friday, October 16, 2009

Apache Tomcat Shutdown Command

So at work I have a machine that runs multiple instances & versions of Apache Tomcat, some of them using different versions of Java.

I have everything configured pretty cleanly (I think) but I noticed that when I use the catalina.sh stop command from any instance, it stops ALL the instances of Tomcat.

Here is the part in catalina.sh that seems to stop all the instances even though the both Java and Tomcat configurations should be specific to just one instance:

"$_RUNJAVA" $JAVA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" stop

I haven't looked at the source of org.apache.catalina.startup.Bootstrap to see exactly what it does with the stop command.

Enter Tomcat's network shutdown command to the rescue: In each server.xml, the <Server>  element allows two attributes: port and shutdown. It might look like this:

<Server port="8005" shutdown="SHUTDOWN">...</Server>

I modified my Tomcat shutdown script to use this network command first to make sure it kills the correct instance. Then, if the instance is still running (which hasn't happened to me yet), I use ps and grep to find the pids of all instances that were started from a particular base directory (each instance, even if it's the same version of Tomcat, has a separate base directory that it uses for its web apps and temp files).

Here is the ingredient list:
1. server.xml, containing the element
2. XSLT stylesheet to convert server.xml to a reduced XML file that contains only the port and shutdown command I need
3. xsltproc command-line tool
4. Netcat (nc) to send the shutdown command to the Tomcat shutdown port
5. Perl script to convert the reduced XML file to a shell command

Here is my XSLT file, shutdown.xslt:

<?xml version="1.0"?>
<service xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="1.0">
<text><xsl:value-of select="Server/@shutdown"/></text>
<port><xsl:value-of select="Server/@port"/></port>
</service>

When used with xsltproc, the shutdown.xslt file generates a small XML file that looks like this:

<?xml version="1.0"?>
<service><text>SHUTDOWN</text><port>8005</port></service>

Here is my Perl script, generate.pl:

#!/usr/bin/perl
local $/ = undef;
my $xml = <STDIN>;
my ($text) = ($xml =~ m{<text>(.*?)</text>});
my ($port) = ($xml =~ m{<port>(.*?)</port>});
print "echo \"$text\" | nc localhost $port";

When given the reduced XML file, generate.pl produced output like this:

echo SHUTDOWN | nc localhost 8005

So putting it all together, the part of my shutdown script that reads server.xml to find the configured shutdown port and the command looks like this:

SHUTDOWN_COMMAND=`xsltproc shutdown.xslt server.xml | perl generate.pl`
$SHUTDOWN_COMMAND

And I can use the same shutdown script with any Tomcat instance without having to duplicate the shutdown port and command information.

Tuesday, June 16, 2009

Simpler instructions

Here's an email I got from Salesforce.com. Notice how they provide one link and then a whole paragraph about how to change the link. They could just provide two links and label them, "this one is to install in production instance", "that one is to install in sandbox instance", and leave out the long paragraph.


To share the app contained in the package with your colleagues, forward the following URL to them:


https://login.salesforce.com/?startURL=%2Fpackaging%2FinstallPackage.apexp%3Fp0%3Dxxxxxxxxxxxxxxx


Note: If you are installing this in a sandbox instance and it was created in production (has a url that starts with https://login.salesforce.com/) you must replace the initial portion of the URL with http://test.salesforce.com/. Likewise, if you are installing a package that was created in a sandbox (has a url that starts with http://test.salesforce.com/) into production you must change the initial portion of the url to https://login.salesforce.com/.

Duplicate entries in Eclipse content assist

I've been asked about this several times already by some Java Programmers so here's the answer:

Go to Eclipse Preferences -> Java -> Editor -> Content Assist -> Advanced, and turn off whichever content assist sources you don't want.



Wednesday, April 29, 2009

How to solve "too much recursion" problem in prototype.js

In prototype 1.6.1_r2, the line numbers are:

Line 3890: expression.scan(/(([\w#:.~&gt;+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {

Line 463:  this.gsub(pattern, iterator);

Line 423: if (Object.isFunction(replacement)) return replacement;

Replacing Event.observe(window,'load',function() {...}) with document.observe('dom:loaded',function() {} doesn't help.

Tuesday, April 28, 2009

Computer Forensics

There are only two kinds of digital evidence:

1's and 0's.

--Anonymous (not me)

Tuesday, March 31, 2009

The Password Problem

For occasional private use, passwords can be just fine to protect a document or folder.

For enterprises, passwords can be bothersome. Imagine the case of Peter, who works at a large company. He has a login for his workstation and email account, access to a dozen intranet applications, and one or more folders on the company network storage drives.  Peter is required to change his passwords every six months. Each application has slightly different rules about what makes a strong enough password, but in general new passwords have a minimum and maximum length, must include characters from certain classes, cannot be based on any English word, and cannot be reset to any one of the last 10 passwords.

Oh, and Peter isn't allowed to write any of them down.

How many millions of people have suffered like Peter?

I have a solution in mind involving public key cryptography and existing infrastructure (PKI) for issuing and validating certificates.

PKI authentication is not new. Apache Httpd has supported client-side certificates for years, and there is a variety of desktop applications that support PKI.  But, it's no surprise that most of the world still uses passwords and not PKI.

There are reasons why passwords are still the dominant authentication method in use today.

One of the major reasons is cost. It's just too expensive to deploy a PKI authentication system. There are many companies ready to take a lot of your money to help you deploy PKI in your organization. If you think you can do it yourself, and you've read some Alice and Bob tutorials, beware of what you don't know. How do you choose which encryption algorithms you want to support? Will there be any real-world issues that the 5-minute tutorial on setting up a certificate authority didn't cover? What are your mistakes going to cost you? For PKI, you definitely need expert help, and it's expensive.

Another major reason is education. Your end-users don't know anything about PKI.  Your IT staff might not know so much either.  They know that personal passwords are easy and corporate passwords are troublesome.  They don't really care for the beautiful design of PKI or have any interest in using the tools to manage their credentials.  They just want to exercise their access and do their job.  Since there's a lot to learn about PKI in order to become a competent user, education is definitely an obstacle.

I intend to make certificate-based authentication easy enough for more enterprises to actually want to do it and enjoy the benefits.   Anyone interested is welcome to send me an email.

Friday, February 01, 2008

Code of Ethics

I'm a card-carrying member of the IEEE, and that means abiding by the IEEE Code of Ethics (pdf). 


The code of ethics embodies honesty, responsibility, cooperation, respect, and concern for the public interest.


That means, if I'm ranting that you suck, it's with the utmost respect and for your own good, so listen up.