Thursday, June 26, 2008

Using java as a shell language

I've been trying to find what shell language I like better as the 'glue' needed between real applications. I've used perl a lot in the past, experimenting with python and ruby now. But I don't want an interpreted language. I really want a compile time language.

So today I figured why not use java.

The main problem is that most scripts are easy to modify and don't require compiling. For example you start your python script with

#!/usr/bin/python

It would be nice if I could do the same for Java. Well now you can.

Introducing the 'JavaLoader'


import java.io.*;
class JavaLoader {
public static void main(String[] args) throws Exception {
String pwd = System.getProperty("user.dir");
System.out.println( "Received argument " + args[0]);
String javaFile = args[0];
if (javaFile.startsWith("./"))
javaFile = javaFile.replace("./","");

// Find class file
String className = (javaFile.split("\\."))[0];

// Comment out the shebang line so we can compile it.
RandomAccessFile file = new RandomAccessFile(javaFile, "rw");
file.seek(0);
file.write("//".getBytes());
file.close();

// Compile it
executeCommand(String.format("javac -cp $CLASSPATH:%s %s",pwd,javaFile));

//Run
executeCommand(String.format("java -cp $CLASSPATH:%s %s",pwd,className));

// Put back #! line.
file = new RandomAccessFile(javaFile, "rw");
file.seek(0);
file.write("#!".getBytes());
file.close();
}
public static void executeCommand(String cmd) throws Exception {
System.out.println("Executing command: [" + cmd + "]");
Process p = Runtime.getRuntime().exec(cmd);
printStream(p.getInputStream());
printStream(p.getErrorStream());
}
public static void printStream(InputStream is) throws Exception{
BufferedReader input = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
}
}


By using this you can now write a script like so:


#!/usr/bin/java JavaLoader

class my {

public static void main(String[] args) {
System.out.println ("my: from here I am in java");
}
}


To execute you first need to make sure the JavaLoader is compiled and in your classpath. Then execute your script. My script was called my.java so I did:


[root@pioneer local]# ./my.java
Received argument ./my.java
Executing command: [javac -cp $CLASSPATH:/usr/local my.java]
Executing command: [java -cp $CLASSPATH:/usr/local my]
my: from here I am in java


This is great no more settling, I get to use Java everywhere now!

No comments: