<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:html="http://www.w3.org/1999/html" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
   <title>semicomplete.com - Jordan Sissel</title>
   <link>http://www.semicomplete.com/blog</link>
   <description>Projects, articles, tips, and experiences on topics ranging from AJAX to Network Security.</description>
   <language>en</language>
   <copyright>Copyright 2006 Jordan Sissel</copyright>
   <ttl>60</ttl>
   <pubDate>Sat, 13 Jun 2009 06:26 GMT</pubDate>
   <managingEditor>jls@semicomplete.com</managingEditor>
   <generator>PyBlosxom http://pyblosxom.sourceforge.net/ 1.3.2 2/13/2006</generator>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/semicomplete/main" type="application/rss+xml" /><item>
   <title>new xdotool version available (20090612)</title>
   <guid isPermaLink="false">geekery/xdotool-20090612</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/Xf9-FRLB1iQ/xdotool-20090612.html</link>
   <description>Hop on over to the &lt;a href="/projects/xdotool"&gt;xdotool project page&lt;/a&gt; and
download the new version.

&lt;p/&gt;

The changelist from the previous announced release is as follows:

&lt;pre&gt;
20090612:
  * Fixed bug where shift modifier was not reset when 'xdotool type' used.
  http://code.google.com/p/semicomplete/issues/detail?id=5
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/xdotool-20090612" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=Xf9-FRLB1iQ:i4LmIzF3Wms:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=Xf9-FRLB1iQ:i4LmIzF3Wms:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=Xf9-FRLB1iQ:i4LmIzF3Wms:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=Xf9-FRLB1iQ:i4LmIzF3Wms:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=Xf9-FRLB1iQ:i4LmIzF3Wms:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/Xf9-FRLB1iQ" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Sat, 13 Jun 2009 06:26 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/xdotool-20090612.html?source=rss20</feedburner:origLink></item>
<item>
   <title>new xdotool version available (20090609)</title>
   <guid isPermaLink="false">geekery/xdotool-20090609</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/Blrx6nHheww/xdotool-20090609.html</link>
   <description>Hop on over to the &lt;a href="/projects/xdotool"&gt;xdotool project page&lt;/a&gt; and
download the new version.

&lt;p/&gt;

The changelist from the previous announced release is as follows:

&lt;pre&gt;
20090609:
  * Add '--delay &lt;delay_in_ms&gt;' to xdotool type. Sets the delay between keys.
  * Add '--window &lt;windowid&gt;' to xdotool type, key, keyup, and keydown.
    This feature (key events with --window &lt;windowid&gt;) only works if the
    application does not reject X events that have 'send_event' set to true.

    Special notes:
    * Firefox appears to ignore all input when it does not have focus.
    * xterm ignores sendevent by default, ctrl+leftclick menu will let you
      enable it.
    * gnome-terminal appears to accept send_event input by default
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/xdotool-20090609" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=Blrx6nHheww:v1bjXLZbOD8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=Blrx6nHheww:v1bjXLZbOD8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=Blrx6nHheww:v1bjXLZbOD8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=Blrx6nHheww:v1bjXLZbOD8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=Blrx6nHheww:v1bjXLZbOD8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/Blrx6nHheww" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 09 Jun 2009 07:01 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/xdotool-20090609.html?source=rss20</feedburner:origLink></item>
<item>
   <title>XSendEvent + LD_PRELOAD == win</title>
   <guid isPermaLink="false">geekery/xsendevent-xdotool-and-ld_preload</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/N812w0A9foM/xsendevent-xdotool-and-ld_preload.html</link>
   <description>As far as feature requests come, for xdotool, one of the more common ones is to
have the ability to send key or mouse events to a specific window, not just the
active one. XTEST (what xdotool uses for key/mouse currently) doesn't let you
specify a window to send events. XSendEvent(3) lets you send hand-crafted
events to a specific window, but most applications ignore these sent events.

&lt;p&gt;

The XEvent struct has a member 'send_event' which is true if the event came
from an XSendEvent call and false otherwise. Programs like firefox and xterm
(by default) ignore many events that have 'send_event' set to true.

&lt;p&gt;

Enter LD_PRELOAD.

&lt;p&gt;

Writing a custom shared library that overrides the default XNextEvent and
XPeekEvent functions allows us to force 'send_event' to always be false, so an
application with this library loaded will happily handle keyboard/mouse events
generated with XSendEvent. I already have a helpful project that lets me write such a shared library: liboverride.

&lt;p&gt;

&lt;pre&gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;X11/Xlib.h&amp;gt;

void hack_send_event(XEvent *ev) {
  switch (ev-&gt;type) {
    case KeyPress: case KeyRelease: case ButtonPress: case ButtonRelease:
      ev-&gt;xany.send_event = False;
      break;
  }
}

override(`XNextEvent', `
  {
    real_func(display, event_return);
    hack_send_event(event_return);
    return;
  }
')
&lt;/pre&gt;

This small bit of liboverride code will give me a shared library I can preload
with LD_PRELOAD. Doing so will ensure that send_event is false for any key or
mouse button events.

&lt;p&gt;

Works well. Now that we have a reliable way to allow XSendEvent I think it's
worth putting this into xdotool.

&lt;img src="/images/spacer.gif?geekery/xsendevent-xdotool-and-ld_preload" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=N812w0A9foM:9X4V1zcgaDU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=N812w0A9foM:9X4V1zcgaDU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=N812w0A9foM:9X4V1zcgaDU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=N812w0A9foM:9X4V1zcgaDU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=N812w0A9foM:9X4V1zcgaDU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/N812w0A9foM" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Sun, 07 Jun 2009 05:28 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/xsendevent-xdotool-and-ld_preload.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Ruby Net::IMAP and Exchange</title>
   <guid isPermaLink="false">geekery/ruby-net-imap-and-exchange</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/DqV2XEySeQY/ruby-net-imap-and-exchange.html</link>
   <description>Exchange's server-side filters are pretty weak, so I decided to work around
them by writing a tool that will fix my inbox and filter mail appropriately so
that any client I use to view mail with (OWA, whatever) has the same view with
no client-local filters. It's likely/possible there's already a tool that does this; let's ignore that possibility for now.

&lt;p&gt;

Ruby comes with Net::IMAP, but it doesn't come with an authenticator that
supports 'PLAIN' auth, so we have to provide one:

&lt;pre&gt;
# Learned the 'PLAIN' expected format from imapsync.
class PlainAuthenticator
  def process(data)
    # Net::IMAP takes care of base64 encoding the result of this...
    return "#{@user}\0#{@user}\0#{@password}"
  end
  
  def initialize(user, password)
    @user = user
    @password = password
  end
end

Net::IMAP::add_authenticator('PLAIN', PlainAuthenticator)
&lt;/pre&gt;

Now that we have that, let's try connecting.
&lt;pre&gt;
imap = Net::IMAP.new("exchange.example.com", "imaps", usessl=true)
imap.authenticate("PLAIN", user, passwd)
&lt;/pre&gt;

This fails, because Exchange's IMAP server ignores the RFC:

&lt;pre&gt;
/usr/lib/ruby/1.8/net/imap.rb:3122:in `parse_error': &lt;b&gt;unexpected token CRLF (expected SPACE)&lt;/b&gt; (Net::IMAP::ResponseParseError)
        from /usr/lib/ruby/1.8/net/imap.rb:2974:in `match'
        from /usr/lib/ruby/1.8/net/imap.rb:1959:in `continue_req'
        from /usr/lib/ruby/1.8/net/imap.rb:1946:in `response'
...
&lt;/pre&gt;

Expected a space, not a crlf. The failure is in continue_req, which expects what the RFC says:

&lt;pre&gt;
continue_req    ::= "+" SPACE (resp_text / base64)
&lt;/pre&gt;

However, Exchange's IMAP server doesn't send a space after the plus. Great,
let's fix that by overriding the continue_req method:

&lt;pre&gt;
# Copied/modified from net/imap.rb, don't modify that file, put this
# in your own code to override the continue_req method
module Net
  class IMAP
    class ResponseParser
      def continue_req
        match(T_PLUS)
        #match(T_SPACE)   # Comment this line out to not expect a space.
        return ContinuationRequest.new(resp_text, @str)
      end
    end
  end
end
&lt;/pre&gt;

Once you've done that, everything else seems to work normally. I have only
tested listing mail folders thus far, but the hacks above allow you to get this
far.

&lt;img src="/images/spacer.gif?geekery/ruby-net-imap-and-exchange" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=DqV2XEySeQY:0ZIrNZD_oJ4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=DqV2XEySeQY:0ZIrNZD_oJ4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=DqV2XEySeQY:0ZIrNZD_oJ4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=DqV2XEySeQY:0ZIrNZD_oJ4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=DqV2XEySeQY:0ZIrNZD_oJ4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/DqV2XEySeQY" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 26 May 2009 08:03 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/ruby-net-imap-and-exchange.html?source=rss20</feedburner:origLink></item>
<item>
   <title>More rmagick/rvg playtime</title>
   <guid isPermaLink="false">geekery/graphing-in-ruby-2</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/jR1TaKwn990/graphing-in-ruby-2.html</link>
   <description>While working on graphs tonight, I found that calculation and labelling of
ticks should be provided by special 'tick' classes. The iterator (the 'each'
method) takes a min and max value and yields ticks in that range. This allows
you to:

&lt;ul&gt;
&lt;li&gt; A 'tick' provider should just be an iterable class (foo.each, etc) which provides the tick position and optional label.&lt;/li&gt;
&lt;li&gt; A graph can have multiple ticks per axis, allowing you to have 'major'
ticks labeled while 'minor' ticks are not labeled, and even more than two
layers of ticks on each axis. &lt;/li&gt;
&lt;li&gt; The same tick classes can easily be used to draw both the graph ticks and
the grid.&lt;/li&gt;
&lt;li&gt; Trivially have 'time format' tickers &lt;/li&gt;
&lt;li&gt; Have a 'smart time ticker' that looks at the min/max and determines the
correct set of time ticks to display (display format, tick distance, tick
alignment, etc). Can use multiple 'time ticker' instances internally (code reuse!)&lt;/li&gt;
&lt;/ul&gt;

I'm sure this has all been though of before, but it's a research experience for me :)

&lt;p&gt;

At any rate, I'm finding myself wondering if RMagick/rvg is really the right
tool. It certainly makes doing graphics trivial, but even for what I see as a
simple graph it takes a little over a second to render, which would hurt
usability if multiple graphs needed rendering simultaneously.

&lt;p&gt;

The bottleneck seems to be with text rendering. If I disable text display in
the graph (tick labels, etc), graph rendering drops by 0.5 seconds (from 1.1).
Switching from 'gif' to 'png' output shaved 0.2 seconds on average of
rendering, which is interesting.

&lt;p&gt;

Today's results, with real data:

&lt;p&gt;
&lt;img src="/files/blogposts/20090520/test.png"&gt;

&lt;p&gt;

&lt;pre&gt;
graph = RPlot::Graph.new(400, 200, "Ping results for www.google.com")
pingsource = RPlot::ArrayDataSource.new
File.open("/b/pingdata").each do |line|
  time,latency = line.split
  pingsource.points &lt;&lt; [time.to_f, latency.to_f]
end
pingsource.points = pingsource.points[-300..-1]
graph.sources &lt;&lt; pingsource
graph.xtickers &lt;&lt; RPlot::SmartTimeTicker.new
graph.ytickers &lt;&lt; RPlot::LabeledTicker.new(alignment=0, step=25)
graph.render("test.png")
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/graphing-in-ruby-2" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=jR1TaKwn990:7wdjUuM5yok:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=jR1TaKwn990:7wdjUuM5yok:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=jR1TaKwn990:7wdjUuM5yok:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=jR1TaKwn990:7wdjUuM5yok:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=jR1TaKwn990:7wdjUuM5yok:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/jR1TaKwn990" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Wed, 20 May 2009 09:27 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/graphing-in-ruby-2.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Graphs in Ruby with RMagick</title>
   <guid isPermaLink="false">geekery/graphing-with-ruby</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/eWWy4M_jeEQ/graphing-with-ruby.html</link>
   <description>I'm always finding myself wanting to graph random data. Gnuplot is nice, but
not enjoyably scriptable. Matplotlib in python is too matlab-ish, or was when I
looked at it last (though it looks much improved now). Some ruby options exist
(even ruby+gnuplot), but none were much to my tastes.

&lt;p&gt;

I started fiddling around with &lt;a
href="http://rmagick.rubyforge.org/"&gt;RMagick&lt;/a&gt; and stumbled across what it
calls "RVG" (ruby vector graphics). From the site:

&lt;blockquote&gt;
RVG (Ruby Vector Graphics) is a facade for RMagick's Draw class that supplies a
drawing API based on the Scalable Vector Graphics W3C recommendation.
&lt;/blockquote&gt;

The API is pretty reasonable and hasn't hindered me yet and feels good after
having hacked with it for a few hours: Simple operations like point
translation, scaling, rotating, flipping, etc are simple in code; the api is
well documented; images can be embedded easily into another which allows for
easily writing modular code.

&lt;p&gt;

Anyway, the goal of this adventure was to come up with something that would
produce non-crappy plots. Main emphasis on having a means to apply axis labels
and ticks that wasn't painful. The result is below: (x-axis ticks are
hour-aligned and have 12 hour steps, y-axis ticks are single-value aligned)

&lt;p&gt;

&lt;img src="/files/blogposts/20090519/testgraph.gif"&gt;

&lt;p&gt;

Here's the code that generates the above graph (using &lt;a
href="http://semicomplete.googlecode.com/svn/rplot/rplot.rb"&gt;rplot.rb&lt;/a&gt;). A
lot of things (like axis label tick alignment and stepping) are hardcoded right
now, but that will obviously change if I decide this project needs attention
(and I don't find something that does the same thing but better).

&lt;pre&gt;
# graph some random stuff, like log(x) and sin(x)
# use time for the 'x' to demo time formatting
# each point is an hour (i * 3600)
graph = RPlot.new(400, 200, "Happy Graph")

points = 60
axis = GraphAxis.new
(1..points).each do |i|
  axis.points &lt;&lt; [Time.now.to_f + i*3600, Math.log(i)]
end

axis2 = GraphAxis.new
(1..points).each do |i|
  axis2.points &lt;&lt; [Time.now.to_f + i*3600, Math.sin((i / 2.0).to_f) + 1]
end

graph.axes &lt;&lt; axis
graph.axes &lt;&lt; axis2

graph.render("/home/jls/public_html/test.gif")
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/graphing-with-ruby" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=eWWy4M_jeEQ:sUpmeDca5AI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=eWWy4M_jeEQ:sUpmeDca5AI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=eWWy4M_jeEQ:sUpmeDca5AI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=eWWy4M_jeEQ:sUpmeDca5AI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=eWWy4M_jeEQ:sUpmeDca5AI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/eWWy4M_jeEQ" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 19 May 2009 07:11 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/graphing-with-ruby.html?source=rss20</feedburner:origLink></item>
<item>
   <title>jps output not correct</title>
   <guid isPermaLink="false">geekery/jps-shows-nothing-useful</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/0AfmMDh3O8g/jps-shows-nothing-useful.html</link>
   <description>A nagios alert checking for some java processes started firing because it
couldn't find those processes. This check used 'jps' to look for those
processes.

&lt;pre&gt;
% sudo /usr/java/jdk1.6.0_04/bin/jps
15071 Jps
% ps -u root | grep -c java
15
&lt;/pre&gt;

I espected lots of output from jps, but there was only the jps process itself.
Confusing. What does jps use to track java processes?

&lt;p&gt;

Your old strace (truss, whatever) friend will help you here:

&lt;pre&gt;
# Always use 'strace -f' on java processes as they spawn new processes/threads
% sudo strace -f /usr/java/jdk1.6.0_04/bin/jps |&amp; grep -F '("/' \
  | fex '"2/{1:2}' | sort | uniq -c | sort -n | tail -5
      5 proc/self 
      5 proc/stat 
     12 usr 
     17 tmp/hsperfdata_root 
    283 usr/java 
&lt;/pre&gt;

It referenced /tmp/hsperfdata_root multiple times. Weird, checking it out:
&lt;pre&gt;
% ls /tmp/hsperfdata_root | wc -l
0
&lt;/pre&gt;

This directory is empty. Looking further around the strace and confirming by
looking at the classes jps invokes
(&lt;a href="http://openjdk.java.net/groups/serviceability/jvmstat/sun/jvmstat/perfdata/monitor/protocol/local/MonitoredHostProvider.html"&gt;sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostProvider&lt;/a&gt;)
shows that /tmp/hsperfdata_&amp;lt;user&amp;gt; is used by each jvm instance. It stores a file named by processes' pid.

&lt;p&gt;

So the question is, why is this directory empty?

&lt;p&gt;

Of the hosts I know run java, it only seems like long-running instances of
java are disappearing from jps, making me think we have a cron job removing
files from /tmp. I found this while looking through cron jobs:

&lt;pre&gt;
% cat /etc/cron.daily/tmpwatch 
/usr/sbin/tmpwatch -x /tmp/.X11-unix -x /tmp/.XIM-unix -x /tmp/.font-unix \
        -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp
/usr/sbin/tmpwatch 720 /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do
    if [ -d "$d" ]; then
        /usr/sbin/tmpwatch -f 720 "$d"
    fi
done
&lt;/pre&gt;

This file comes from the tmpwatch rpm, which appears to come base installed on
CentOS.  This means that for every file in /tmp (except those specified by '-x
dir') are being deleted if they are older than 240 hours (10 days). As an FYI,
the default time value inspected is the file's atime, so if you mount noatime,
the accesstime is not reliable.

&lt;p&gt;

Ultimately, we need to add a new set of flags to the cronjob that excludes
/tmp/hsperfdata_*. This should keep me from being paged when a java process
lives for more than 10 days ;)

&lt;p&gt;

Additionally, it makes me think that the people who use CentOS don't use Java
or don't monitor their java processes with jps.


&lt;img src="/images/spacer.gif?geekery/jps-shows-nothing-useful" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=0AfmMDh3O8g:nA9JqJD1zmI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=0AfmMDh3O8g:nA9JqJD1zmI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=0AfmMDh3O8g:nA9JqJD1zmI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=0AfmMDh3O8g:nA9JqJD1zmI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=0AfmMDh3O8g:nA9JqJD1zmI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/0AfmMDh3O8g" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Sun, 17 May 2009 03:46 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/jps-shows-nothing-useful.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Shebang (#!) fix.</title>
   <guid isPermaLink="false">geekery/shebang-fix</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/kz54k-Jfvrk/shebang-fix.html</link>
   <description>Most shebang implementations seem to behave contrary to my expectations.

&lt;p&gt;

As an example, prior to today, I would have expected the following script to
output 'debug: true'

&lt;pre&gt;
#!/usr/bin/env ruby -d
puts "debug: #{$DEBUG}"
&lt;/pre&gt;

Running it, I get this:

&lt;pre&gt;
% ./test.rb
/usr/bin/env: ruby -d: No such file or directory
&lt;/pre&gt;

This is because the 'program' executed is '/usr/bin/env' and the first argument
passed is 'ruby -d', exactly as if you had run: /usr/bin/env "ruby -d"

&lt;p&gt;

My expectation was that the above would behave exactly like this:
&lt;pre&gt;
% /usr/bin/env ruby -d test.rb
debug: true
&lt;/pre&gt;

It doesn't. The workaround, however, is pretty trivial. It's only &lt;a
href="http://semicomplete.googlecode.com/svn/codesamples/shebang.c"&gt;a few lines
of C&lt;/a&gt; to get me a program that works as I want. I call the program
'shebang'. Why is it C and not a script? Because most platforms have a
requirement that the program being executed from the shebang line be a binary,
not another script.

&lt;p&gt;

&lt;pre&gt;
#!/usr/local/bin/shebang ruby -d
puts "debug: #{$DEBUG}"
&lt;/pre&gt;

Now run the script again, with our new shebang line:
&lt;pre&gt;
% ./test.rb
debug: true
&lt;/pre&gt;

Simple and works perfectly.

&lt;img src="/images/spacer.gif?geekery/shebang-fix" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=kz54k-Jfvrk:eIlYnWGPMhk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=kz54k-Jfvrk:eIlYnWGPMhk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=kz54k-Jfvrk:eIlYnWGPMhk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=kz54k-Jfvrk:eIlYnWGPMhk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=kz54k-Jfvrk:eIlYnWGPMhk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/kz54k-Jfvrk" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Wed, 01 Apr 2009 07:40 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/shebang-fix.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Where have I been?</title>
   <guid isPermaLink="false">geekery/unstealth-onlive</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/C4r05Azr15c/unstealth-onlive.html</link>
   <description>I've been pretty silent on this site since January. This is because I've been
busy at work and haven't had the time and energy to throw into writing here,
unfortunately. Though, each time I think about my lack of recent writing, I
remind myself that I 'm still well over average for posting since writing 23 of
the 25 articles on &lt;a href="http://sysadvent.blogspot.com/"&gt;sysadvent&lt;/a&gt;.

&lt;p&gt;

Fortunately, I can now open up about the company I work for since we surfaced
two days ago. I work for &lt;a href="http://www.onlive.com/"&gt;OnLive&lt;/a&gt;.

&lt;p&gt;

As things calm down I should be able to dump more time into writing here.

&lt;img src="/images/spacer.gif?geekery/unstealth-onlive" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=C4r05Azr15c:Zye9ujNVS0Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=C4r05Azr15c:Zye9ujNVS0Y:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=C4r05Azr15c:Zye9ujNVS0Y:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=C4r05Azr15c:Zye9ujNVS0Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=C4r05Azr15c:Zye9ujNVS0Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/C4r05Azr15c" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Wed, 25 Mar 2009 17:22 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/unstealth-onlive.html?source=rss20</feedburner:origLink></item>
<item>
   <title>xdotool 20090126 available</title>
   <guid isPermaLink="false">geekery/xdotool-20090126</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/ThXHhSLTgKk/xdotool-20090126.html</link>
   <description>A new release of xdotool is available. It fixes &lt;a href="http://code.google.com/p/semicomplete/issues/list?can=1&amp;q=label%3Axdotool-20090126"&gt;two bugs&lt;/a&gt; that were moderately annoying.

&lt;pre&gt;
20090126:
  * Change the default behavior of 'getwindowfocus' to get the first
    ancestor-or-self window that has WM_CLASS set. WM_CLASS will be set on
    (all?) top-level windows and it's possible that the currently focused window
    according to X is not a top-level window. To use the previous behavior, use
    'getwindowfocus -f'
  * Make 'xdotool key at' work correctly. 'at' is usually Shift+2, for example.
    Now all shifted characters should work, but I've only tested on a US
    keyboard.
  * Minor Makefile fixes for package maintainers.
&lt;/pre&gt;

I've tested it in GNOME and Ion-3 with success.

&lt;p&gt;

Download: &lt;a href="http://semicomplete.googlecode.com/files/xdotool-20090126.tar.gz"&gt;xdotool-20090126.tar.gz&lt;/a&gt;

&lt;img src="/images/spacer.gif?geekery/xdotool-20090126" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=ThXHhSLTgKk:ED0knx0Wg4o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=ThXHhSLTgKk:ED0knx0Wg4o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=ThXHhSLTgKk:ED0knx0Wg4o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=ThXHhSLTgKk:ED0knx0Wg4o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=ThXHhSLTgKk:ED0knx0Wg4o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/ThXHhSLTgKk" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Mon, 26 Jan 2009 11:15 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/xdotool-20090126.html?source=rss20</feedburner:origLink></item>
</channel>
</rss>
