Cool Use of Jython

I just had to share this. I am working on a very large project using BEA‘s WebLogic 7. This project takes a good 10 minutes to go through an entire compile/deploy cycle. This is a real hassle when I need to noodle something out, test some idea, etc. I use Jython for all manner of nifty things including testing things from the client side of my app, but what if I wanted to test something from within the container? Sure I could write a Cactus test (and I have written many), but adding/changing a Cactus test results in a compile/deploy cycle. What I needed was something better.

What I came up with is a truly (dirty) hack that is totally insecure yet really useful. (IOW, don’t put it on a production server.)

I embeded a Jython interpreter inside an Apache Axis web service. I then have a short Jython script on the client side that sends an arbitraty script to the server, which is executed and then the stdout/stderr are bundled up and sent back in the SOAP response. I think this is really cool.

The files involved are

The web service is where the real work occurs, but it’s brain-dead simple. Here’s JythonWebService

package com.joeygibson.soap;

import java.io.StringWriter;

import org.python.util.PythonInterpreter;
import org.python.core.*;

public class JythonWebService
{
    private PythonInterpreter interp =
        new PythonInterpreter();
    Writer out = new StringWriter();
    Writer err = new StringWriter();

    public JythonWebService()
    {
        super();

        interp.setOut(out);
        interp.setErr(err);
    }

    public String exec(String script)
    {
        interp.exec(script);

        StringBuffer results =
            new StringBuffer(
                "----- StdOut -----nn");
        results.append(out.toString());
        results.append(
            "nn----- StdErr -----nn");
        results.append(err.toString());

        return results.toString();
    }
}

Simple, eh? We create the Jython interpreter and then give it two StringWriters that will capture stdout and stderr, respectively. Then in the exec method we accept the script from the SOAP envelope, let the interpreter execute it, and then bundle up the stdout and stderr with nice little markers to differentiate them. That then goes back over the wire to the caller.

Next is remote.py that executes the service from the client side.

import string, sys
from java.io import *
from org.apache.axis import *
from org.apache.axis.client import *
from javax.xml.namespace import QName

global service, call

service = Service()
call = service.createCall()
call.setTargetEndpointAddress(
    "http://localhost:7001/ivr/services/AxisServlet")
call.setOperationName(
    QName("JythonWebService", "exec"))

f = open(sys.argv[1])
scriptLines = f.readlines()
f.close()

script = string.join(scriptLines, "")

ret = call.invoke([script])
print ret

Here we first import the necessary packages/classes from both Java and Jython. We then create the Axis Service and Call objects, setting the endpoint and operation name on the call. Next we load up the specifed file (this could easily be changed to support multiple scripts from the command line), concatenate each line into one big string, and then execute the web service. The script is then passed as the sole argument (wrapped in an array) to the exec method of Call, which executes the remote call. Finally the result is printed.

Next in line is remote.bat the batch file I used to execute the client. It just sets up a reasonable classpath and then invokes Jython.

@ECHO OFF
setlocal

set CLASSPATH=<jars from the axis/lib directory>
call jython remote.py %*

This adds all the jar files in the axis/lib directory to the classpath and then runs our remote.py script through Jython. You may have to get creative with how you set your classpath. I use 4NT as my command prompt, which has much longer command line allowances. The setting of the classpath can be a pretty long string and CMD.exe may barf on it. YMMV.

Finally we need to test something. Here’s test.py that will run on the server via our web service

from javax.naming import *

ic = InitialContext()
vv = ic.lookup("ejb/VVLookup").create()
l = vv.getValidValuesForFieldNumber(1558)

for i in l: print i

Obviosly you would have to tailor this for your setup since it’s doubtful that you have a stateless session bean deployed at ejb/VVLookup… Anyway, you can see that I create an InitialContext (with no parameters since we’re inside the container) do a lookup, execute a method that returns a collection and then iterate over it, printing them out. Since print goes to stdout, the output will be captured and then returned to the client.

That’s it! If anyone want’s a copy, let me know. It’s so simple, though, that you could just do it yourself.

My Crappy DSL service

My DSL service has been really sucking for the past two days. I quickly blamed it on DirecTV DSL which used to be Telocity. The reason I so quickly blamed them is because they announcd on Dec. 18 that they were closing up shop. I think they have a problem and are letting the network slip into oblivion, depsite their statements that they would keep it running until January 16; it may be running, but not running well.

So early this morning I check my router logs and I see lots of attempts to come in through port 137. What’s port 137? It’s NetBios. This is the port that Windows networking uses to do name resolution. It’s an apparently easy exploit to get in this way on unsecure systems. Mine is secure (my router blocks every port but the four or five that I use), but the net result is that my router could get overloaded, thus producing a Denial of Service.

There are also attempts to get in on port 1433 which is the port that Microsoft SQL Server runs on. This exploit hits folks who never setup an admin password when they installed SQL Server. I have to say that someone who installs a database and doesn’t change the admin password almost deserves to get hacked. Of course vendors who ship software that doesn’t force you to even set an admin password should be shot…

I’m seriously bummed about this. I’ve already initiated a switch to SpeakEasy.net to continue my DSL service, but I don’t know how long it will take to get that moved over. I’ve had DSL for about 1.5 years now, and the thought of not having it is something I don’t like to think about…

Googling From Blosxom

I’ve made a few changes to my copy of Blosxom to add the little “Google” link you see at the end of this entry. I’ve seen this on other blogs here and there so I decided to add it to mine. It consists of a subroutine called buildGoogle that takes the second line of each story file and builds the Google URL with the query string built from your keywords. The second line of the file will only be used as keywords if the line starts with KW:. If it starts with anything other than that, it will be included as part of the body. For example, a file with this

KW: blosxom perl blog

as its second line will produce this

 | Google

To include the link itself in your stories, edit your story.html and add $google wherever you want the link to show up. If the link was not built because you didn’t have a KW: line, then nothing will show up. This is from my story.html. Notice it comes right after code creating the perma-link.

 #$google 

Here is the patch if you would like to use it.

Merry Christmas Everyone!

Well, it’s 00:29 on December 26… Christmas is officially over. I always get bummed after Christmas; the lights don’t seem as pretty and the tree seems lonely and sad. We had a great Christmas here. My son, Thomas got everything he had asked for and more. My wife and I got a nice new digital camera that I’ve been trying out. Very nice and easy to use. I just wish it didn’t store its images in JPG format. It’s a 4 megapixel camera so the jpeg-iness probably won’t really be a problem, I just don’t like lossy compression without a conscious decision to use it…

Anyway, so Christmas was good for us. It was good in another respect too: I got my laptop setup with Red Hat Linux. I’m using their default window manager, which is built on/with/is Gnome. Looks great. Feels pretty good. Still a bit tricky to do things that should be easy like adding icons to the main menu… I did get it working with my LinkSys WPC11 wireless LAN card. I can pretty easily switch between a hard line and the wireless, which is nice. I installed the latest Mozilla, Eclipse and Java dev kit, so I’m really cooking now. I still need to install DB2 and WebLogic Server 7 to get my day-job project going. (I just got JBoss going…)

Then for fun I need to update Ruby, Python and the myriad Eclipse plugins that I use regularly. It’s taking time, but I’m pretty happy with the results so far.

Anyone Using Komodo?

I’ve seen this IDE from ActiveState for a while now called Komodo. Is anyone using it? It looks pretty nice. Quite a bit nicer than it did about a year or so ago when I first saw it. Can anyone recommend a better Perl/Python/Ruby editor? I’m looking at the latest pre-release of FreeRIDE which will be a very nice editor when it’s finished. If you are into Ruby you should give FreeRIDE a try. The 0.5.0 release candidate came out today.

Time To Retaliate

The news today is that Iraq has shot down one of our unmanned Predator aircraft. Those people have been firing on our planes patrolling the no-fly zones for some time now, and we’ve only recently started really hitting back. Thankfully they’ve never taken out a manned aircraft. This time it was a drone, but next time it could be for real. The pattern for the last several times that they’ve fired on us was the levelling of the installation that fired, or the radar station that peppered the aircraft for the missile to hit. It’s time to take it up a notch and rather than just hitting the particular installation that fired the missile, we need to take out, say, 10 of their bases. And then increase the number with each infraction.

“He pulls a knife, you pull a gun. He sends one of yours to the hospital, you send one of his to the morgue. That’s the Chicago way…”

My Kingdom For A Decent (Free) ISO Writer!

I’ve decided to Linux-ify my company laptop so I downloaded all 5 ISO images or Red Hat Linux 8.0. All 3,325,001,728 bytes of it. Yes, DSL is a beautiful thing. So I’ve got these ISO images now and I need to write them to CD. There is aparently a metric ton of software for Linux systems that will write these things to CD, but precious little for Wintel boxen. But of course all that cool free software doesn’t help me. I need to get them written to CD before I can install Linux and have access to these great tools that will let me write them to cd… Ah well… I tried using this ISO Recoder Power Toy but it didn’t work very well. Most of the time it told me I had a non-writable cd in the drive when I knew darn well it was a virgin CD-R. It could be my crappy CD-RW drive, but I’m not sure. So I’m going to install an old copy of something I had laying around on the laptop which has a working CD-R drive. Fun fun.