Tuesday, February 28, 2012

cslistener on mac osx (on port 9000)


One day, I was unable to start a java server (Sonar) on port 9000.   It turns out something was already listening:
sudo netstat -an | grep 9000
tcp4       0      0  127.0.0.1.9000         *.*                    LISTEN
tcp4       0      0  127.0.0.1.49155        127.0.0.1.9000         CLOSE_WAIT
tcp4       0      0  127.0.0.1.9000         127.0.0.1.49155        FIN_WAIT_2

To find out exactly what was listening:

sudo lsof -i TCP:9000
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
SecureCli 279 bone   13u  IPv4 0x081e5b18      0t0  TCP localhost:49155->localhost:cslistener (CLOSE_WAIT)
SR_Servic 613 root   68u  IPv4 0x081e6b58      0t0  TCP localhost:cslistener (LISTEN)

Google didn't turn up and info on cslistener. So, I hunted down the process. To locate the command and kill it:

locate SR_Service
/opt/CPsrsc-50/bin/SR_Service

A quick read of the copyright in /opt/CPsrsc-50 revealed that the culprit was Checkpoint firewall. Sure enough, a quick uninstall of Checkpoint and 9000 was happily available.

Hopefully this helps people that can't track down cslistener.


Tuesday, February 7, 2012

Virgil moved to Github

To make it easier for people to contribute to Virgil, we've moved the project to github!
https://github.com/hmsonline/virgil

As a side note...

I've succumb to the force and created a twitter account.
@boneill42
https://twitter.com/#!/boneill42

Friday, February 3, 2012

Cassandra Validation Classes / Types


Cassandra validates column names and row keys using validation classes.
This is put in place when you construct a columnFamily.

As an example, in the Thrift API:

CfDef columnFamily = new CfDef(KEYSPACE, COLUMN_FAMILY);
columnFamily.setKey_validation_class("UTF8Type");
columnFamily.setDefault_validation_class("UTF8Type");



The default_validation_class is used to validate row keys.
The key_validation_class is used to validate column names.

Googling didn't provide a handy list of validation classes for Cassandra.
So, here it is:

AsciiType.java BooleanType.java 
BytesType.java 
CompositeType.java 
DateType.java 
DecimalType.java 
DoubleType.java 
DynamicCompositeType.java 
FloatType.java 
Int32Type.java 
IntegerType.java 
LexicalUUIDType.java 
LocalByPartionerType.java 
LongType.java 
ReversedType.java 
TimeUUIDType.java 
TypeParser.java 
UTF8Type.java 
UUIDType.java

Wednesday, February 1, 2012

Bundling Gems in Jars/Wars for Jruby

As part of Virgil's ability to deploy ruby scripts to a remote Hadoop cluster, we needed to package gems' into that Hadoop jar.  After a bit of monkeying around, we got it.

This is the key piece of information:
"Because the operation of Java's classpath and Ruby's load path are so similar, especially under JRuby, they are unified in JRuby 1.1. This results in a number of unified capabilities:...

  • Everything in the Java classpath is considered to be a load path entry, so .rb scripts, for example, contained in JAR files, are loadable."
First thing you need is to actually get your hands on the gem.  To do this, you can run jruby to grab the gem.

java -jar jruby-complete-1.6.0.jar -S gem install -i rest-client rest-client --no-rdoc --no-ri


This will fetch the gems and install them into the current directory under the directory "rest-client".  In that subdirectory you'll find: bin, cache, doc, gems and specifications.  The actual code for the gems is found in the gems directory.  In the case of rest-client, you'll find two directories that contain the code: mime-types-1.17.2 and rest-client-1.6.7.

This is what you need to bundle into the jar.  We copied those two directories into our java project under src/main/resources/gems/.

One approach would be to simply include those directories on your classpath.  Another approach is to programmatically adjust the loadpath to include those directories.   You can do this with the following lines:

List paths = new ArrayList(); 
paths.add("gems/rest-client-1.6.7/lib/"); 
paths.add("gems/mime-types-1.17.2/lib/"); 
this.rubyContainer = new ScriptingContainer(LocalContextScope.CONCURRENT); this.rubyContainer.setLoadPaths(paths);

Then, when using this.rubyContainer you'll be able to run ruby files that require the rest-client.

Since the ruby scripts are actually loaded via the classpath (from the loadpath), jruby is happy loading them from within a jar.  In our case, we built the jar using maven and the gems were included in the jar because we put them under src/main/resources/gems.

Its that easy.  Happy rubying.