Archive for October, 2007

Bullet-Proof Jasper Reports and PHP

Saturday, October 27th, 2007

Okay, so I got a fair bit of traffic about my last entry where I attempted to explain how I managed to get PHP to talk to Jasper through use of the PHP/Java Bridge instead of having to resort to running external programs through exec, which is undesirable for a number of reasons (including parameter passing and performance).

I’ve done a bit more work with Jasper using PHP and I can say that a few simple steps can make life infinitely easier.

First of all: Setting up and using the PHP/Java Bridge.

You don’t need to use the extension, there is a library written in pure PHP that you can use as a fall-back. When populating a report with Jasper, you don’t use that many Java calls so the reduced performance should not impact on your application too much. If you are calling a fair bit of Java from PHP, I would attempt to get the extension working as the performance is increased dramatically.

Here is a nice little function from the PHP/Java Bridge examples that detects if the extension is loaded and falls back to the native bridge if it isn’t available:

It assumes that you have the PHP implementation in the “java” directory. See the guide below for downloading this.

Second: Classpath is still screwy.

There is something about the bridge that I cannot figure out. Regardless of environment variables, they way you use java_require, settings in php.ini or any other setting this still seems to stuff up. There is one solution that I attempted to steer away from as I did not see it as ideal, however please believe me when I say that this single step will save you hours, if not days of frustration.

Put all the Jasper libraries into your jre lib/ext directory. Trust me.

I have got things tantalisingly close to working with other methods of making the libraries available to the bridge, and even succeeded on the odd occasion. However this is the only reproducible guaranteed way to get rid of those class woes once and for all.

By using the PHP implementation of the bridge and putting your jars into the lib/ext directory, you should be able to get this to work on any platform. I have got it working on Windows and Linux, but by removing any reliance on external settings this should work on pretty much any platform.

Third: Use the JDT compiler.

This little tid-bit of gold was dropped on my blog by Lucian, one of the primary contributors to Jasper’s continued development (thank you).

If you have the jdt-compiler jar in your lib/ext folder as well, the problem of java having a different running directory to that of PHP becomes a non-issue. Most importantly however, this removes the need to set environment variables!

With my previous approach to getting jasper working, I resorted to writing a wrapper class primarily because you can not set the “jasper.reports.compile.temp” and “jasper.reports.compile.class.path” through the bridge (it doesn’t work). Setting these gave the javac compiler the information it needed to compile the report, without them it failed horribly. The JDT compiler does all this stuff in memory, it is hot.

Lastly, the easiest way to get all the libraries required for running Jasper is to download and install iReport then grab them from the lib directory. Please pay attention to the licensing! Some of these libraries like the mysql connector are under the GPL so distributing it with a non-GPL product will be frowned upon.

Putting it all together.

After this work, compiling and running a report from PHP becomes a simple exercise in translating from the Java examples to PHP:

Note that you still need to use complete class names, otherwise you will get Class Not Found problems.

Okay, a quick guide to running Jasper from PHP:

  1. Setup the environment as per normal with PHP and Java (I use WAMP on Windows);
  2. Download the latest iReport software and install it on your workstation;
  3. Grab all of the files from “C:\Program Files\JasperSoft\iReport-2.0.2\lib” (version number will change) and copy them into your java’s lib/ext directory;
  4. Download the latest version of the PHP/Java Bridge with source and unzip it;
  5. Unzip the src.zip file (should be included in the download) and copy the contents of the “java” directory to your PHP app.
  6. If you want to use the stand-alone Java Server (easiest), grab the JavaBridge.jar from the ext directory (in the download) and copy it into the “java” directory you just placed in your PHP app.For production, you will probably want to use the Java extension and configure it to come up with your web server. There are a few configuration options here (including J2EE back-ends and the like), and the PHP/Java Bridge website explains how to get working with them.
  7. Start the Java backend (java –jar JavaBridge.jar). This will usually bring up a dialog asking what port to use, however you have command-line options as well if you are running headless.
  8. Try it out!!

Here is an example report: test.jrxml
And some example PHP code to compile, run it and send it to your browser: index.php.txt

Other things to note:

  • Please cache the compiled version of your reports; otherwise you will be waiting for the report to compile every time you run one. I have some example code for doing this in my ReportGenerator class I used in my previous post.

Hopefully people will find this approach a little more straight-forward.

Enjoy!

Reading Apple Mail Attachments

Wednesday, October 24th, 2007

Okay, so Jess is finishing up her Masters of Project Management with many of the assignments having gone to and from people for review via email.

One problem however: Enter Apple Mail, exit attachments.

Instead of the nicely revised document, you get a nice, anonymous, useless attachment. It’s frustrating to know that this “noname” attachment contains all of the precious work, just out of reach.

So, on opening this attachment (in vim, of course) I found that it was basically a base-64 encoded version of the document and some other stuff, with normalish MIME headers. Sort of like an attachment in an attachment. So by grabbing the most important (biggest) bit of encoded text, stripping out the new lines and un-encoding it, I could successfully get the document back and everyone was happy.

Having needed to use this script on a few occasions, I decided that it might be useful for some others, so here you go:

Of course I can’t be held responsible for the script not working, destroying priceless documents, killing your cat or anything else.

I have also put the script up on the server for quick reference: http://www.rjohnson.id.au/attachment_decoder/
Hope this is useful to someone out there…