I've been writing a lot of one-off type applications at work lately, which is always kind of a joy for me because these sorts of applications don't need to be maintained or supported in any way, which means I can write them however I want.
So I write them in Python :)
Jython allows me to interface with all the plethora of Java libraries that we use at work, and it lets me program in a language that not only I can tolerate, but one that I respect and love.
But even though these are one-off applications, they still need to be easy to use, and in some cases I won't even be the one running the application. I want these applications to just work damnit.
So, packaging my Jython application into a single executable jar file that contains all of the third party dependancies inside is my goal. I want to send the user the jar file, have them double click on it, and have it immediately start running. It can't get a whole lot easier than that.
The Jython wiki has a page about doing something along these lines. The recipe there called the Jar Method works quite well. The one drawback that it has is that all of the Java dependancies need to be exploded into the main jar root, which when you're dealing with dozens of jar dependancies, it can start to get tedious, messy, and in some cases will even violate the license of a particular library.
One-Jar is a special class loader that can load a jar file that is inside of another jar file, something that the regular class loader from Sun is incapable of doing. Using One-Jar lets my application reside inside of a jar file and contain all my dependancies as seperate jar files inside the main jar file.
I've created a sample project that shows how I normally create a new Jython project hosted inside a single jar file with One-Jar. You'll need the following tools to check out the project:
- A Java SDK (tested with OpenJDK 1.6)
- Apache Ant (tested with version 1.7)
- Git (to checkout the project)
Check out the project like so:
git clone git://github.com/EnigmaCurry/Single-JAR-Jython-Example.git
Build the project:
cd single-jar-jython-example ant
Run the example by double clicking it or via the command line:
java -jar JythonExcelExample.jar
This is just a demonstration app, it doesn't do a whole lot, it outputs an excel file in the current directory listing some computer parts. The point of the application is to show how Jython can integrate with existing Java third-party libraries (in this case Apache POI.)
Instructions for basing your own application on this example are contained inside the README.txt file.
I love programming in Python. I get paid to write Java though. Due to Java's verboseness, and lack of a REPL, this can be very frustrating for me.
In Python, the usual way I explore a new library or mock up a new idea is to immediately start coding in Python's interactive interpreter (or REPL). This is often times more efficient than reading (let alone finding) the documentation for the library. I can quickly see if something is going to work before I code inside my larger application.
Java doesn't have an interactive interpreter.. but Jython does! However, setting up Jython, especially interfacing with an already large Java application, can be difficult. One such difficult situation I deal with at work is in Weblogic. With Weblogic, I deploy my application directly to a running Weblogic server, and I never get to see a console in this process, so how am I ever going to run a Jython interactive interpreter?
This morning I got bored and wrote up a quick solution: JythonShellServer. JythonShellServer embeds into any Java application and starts a Telnet server that serves up Jython interactive shells. You can push any Java object that you want to manipulate into Jython's local environment. Run "telnet localhost 7000" and you can use Python code to explore your entire application's running environment.
JythonShellServer works, but I only just wrote it this morning, so consider it alpha quality at the moment. Check out the project page on github.
I've been coding in Python for two years now. I've recently been reteaching myself Java because some projects I'm working on require it. So far, about the only fun thing about it has been setting up Emacs abbreviations to handle all of Java's verbose syntax. I am simply amazed at how verbose Java is! Just to illustrate my frustration I coded one of the exercises I was working on in Java as well as in Python:
Yes, both of these code samples do the exact same thing.
On the top is Python. 17 lines of very readable code. On the bottom, weighing in at 28 lines, is Java. Brackets and semicolons are everywhere -- Redundant type declarations and "new" object instantiations -- No syntactic sugar in sight except for the "+" operator that I'm not even allowed to overload myself!
I even think I'm being a bit generous to Java, in the way I've formatted the above code, I've only used a newline when I thought it adds to the readability. You'll note that I closed three whole blocks of code on line 23 instead of on separate lines. Yea, I could start doing this everywhere else to save space but that starts to make the readability of the code much worse than it already is.
Sure, Java is a fine language, it certainly has a long life still ahead of it and will continue to grow and mature... but coming down from a two year long 'Python high' and coming back to Java is.. well.. less than thrilling.
Update: The original java code had newbie-esque syntactical errors that prevented compilation as well as a much larger technical problem: when using an Array as the input for an ArrayList it changes the behaviour of the ArrayList such that it is fixed length meaning it no longer implements a removeAll() method (nor even an add() method, what's a list if you can't add items?!?) Wrapping a Array.asList inside of the ArrayList fixes it, but logically adds yet another line of code and further obfuscates things.