On the panel Structured Design and Modern Software Practices, Ed Yourdan told this joke (apropos someone using UML for user interface modelling - but he told it much better than I can):
An elephant trainer at a circus decided to teach his elephant to paint. After a while, he's taught it how to hold a paint brush. Later, he manages to teach the elephant how to dip the paint brush in the paint. Some time later still, he's managed to teach the elephant to stroke the brush against the canvas. Many years go by, and he teaches the elephant to paint better and better. Then one day, a reporter hears the story and comes to see the elephant paint. The elephant trainer says, "watch this"; he gets the reporter to sit on a stool and pose, and tells the elephant to paint a portrait of the reporter. The elephant paints deftly, with apparent confidence. After 20 minutes the reporter is excited to see the resulting portrait. The elephant trainer proudly turns the canvas around so the reporter can see it. It's just a mess of random colors. The reporter says "errr, it's crap". The elephant trainer is unperturbed. He beams with enthusiasm and pride "Maybe. But isn't it amazing - I've taught an elephant to paint!".
I'd like to coin the phrase "teaching an elephant to paint". In a meeting, if I say "yes, we could do that, but it would be teaching an elephant to paint" then I hope you'll know what I mean.
I discovered something yesterday that is just so cool; it's cooler than cool; it's ice cold. Those clever Jython folks implemented the python module BaseHTTPServer - I didn't realise this the last time I looked at Jython (which I thought was pretty clever just as a scripting language for Java).
Sometimes it's useful to get data out of a database and put it on a web page. (If you don't know what I'm talking about - that's what Enterprise IT is). Sometimes it's useful to do this just for development, independent of the actual production code. For example: for tools, visualisation, testing, system debugging, setting up test data etc.
1In Ruby on Rails or Django (see A comparison of Django with Rails) it would be less, but that's not what this article is about.
Using Jython's BaseHTTPServer you can write handy little Web Apps in hardly any code, really quickly, still using your Java Enterprise Heavy Duty IT code if you need.
Here's an example (which I hope will also be useful to someone out there). I've got Jython 2.1 installed, MySql running, and the MySql JDBC driver on the classpath2.
This creates a web app that shows you the contents of any table in the database. Run this code (having configured database, user, password to suit), open a web browser on "http://localhost:8000/table/foo" to see the contents of table "foo". Note - this has no protection against sql injection attacks so be careful where you run this. This code is provided under the GNU Lesser General Public License and has NO WARRANTY.
import BaseHTTPServer, urllib, java.lang, java.sql
java.lang.Class.forName('com.mysql.jdbc.Driver')
url = 'jdbc:mysql://localhost:3306/database'
class DBHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
path = urllib.unquote(self.path[1:]).split('/')
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
if path[0] != 'table' or len(path) != 2:
self.wfile.write("don't understand "+str(path))
else:
con = java.sql.DriverManager.getConnection(url,'user','password')
s = con.createStatement()
table = path[1]
r = s.executeQuery("select * from "+table)
html = java.lang.StringBuffer("<html><head></head><body><table border=1>")
numCols = r.getMetaData().getColumnCount()
while(r.next()):
values = [str(r.getString(i)) for i in range(1, numCols+1)]
html.append("<tr><td>")
html.append("</td><td>".join(values))
html.append("</td></tr>")
r.close()
s.close()
con.close()
html.append("</table></body></html>")
self.wfile.write(html.toString())
server_address = ('', 8000)
httpd = BaseHTTPServer.HTTPServer(server_address, DBHandler)
httpd.serve_forever()
An example of it's use, (having done the Django tutorial in case you recognise the table name or data - although this has got nothing to do with Django as such), http://localhost:8000/table/polls_polls shows me:
| 1 | 1 | Not much | 3 |
| 2 | 1 | The sky | 1 |
Adding column names is left as an exercise for the interested reader.
2Note that jython didn't like it when the classpath contained a directory "mysql-connector-java-3.1.11" - it didn't like the mix of "-" and ".". I don't know if this is a known issue - I'll look into it.
Someone read this and asked what the big deal was. He mostly uses Microsoft technologies rather than Java; I've added this section to answer the question.
In Java, you'd usually have to have an application server installed, configured and running, and write a servlet or equivalent and compile/deploy into the application server.
Using the code shown here, you're not having to do any of this. The code shown is all you need - it's the whole server thing - the whole database access thing too - no separate application server or configuration or deployment. Just run that code - it starts it's own server almost instantly. Just starting up some application servers takes a minute. Installing multiple application servers so you can have a lighter weight one for tools is an option, but configuring them can be lots of hassle. There are exceptions, like Orion, which is relatively straightforward, but even in that, it's more hassle than copying and pasting the code I've shown and editing to suit. At some places, there would be techno-political issues of installing another application server. Installing Jython for scripting tools is less likely to be objected too - in that sense, in some cases, it could be considered partially a technical solution to a techno-political problem.
If you were using .NET I guess you'd usually have IIS already installed. In many ways, this is an example of the classic Microsoft vs Java technical differences. Microsoft stuff often being very simple for simple things but eventually getting horrible for difficult things (for example, being difficult to script IIS configuration) and Java sometimes being less simple for simple things, but with more things configurable and capable of doing more difficult things. (For some things Java is also very simple for simple things - but probably less so, on average, than Microsoft equivalents, but I probably shouldn't have even started along that line as I'll probably get lots of "my technologies better than yours" comments).
I was so impressed to find that BaseHTTPServer is implemented for Jython. It makes it really easy to create a HTTPServer.
Just to clarify, in case you haven't used Jython - you can import any of your existing Java code and use it in a jython program like the example shown.
The example code isn't how I'd normally look at the contents of a table in a database; I'd usually use something like SQuirreL - this is just an example that I hope you find useful as a starting point for implementing other useful things.