Compiling Custom Event Gateways For Dummies
First off, let me say that I am not a java programmer. I've done a lot of java integration in coldfusion, but that has little to do with actual java programming.
I recently had a need for a very simple event gateway - one that would basically make a CFC method call every XX seconds. Kind of like a scheduled task, except scheduled tasks unnecessarily tax the web server and run no more often than once every minute.
There were many "GOTCHYAS" along the way in this experience and I want to share some of them. If you, like me, are not a real java programmer, you may find some of these tips useful.
I chose to start with the DirectoryWatcher gateway - an actual working gateway that read a config file where things occurred on an interval. In the section where it read the properties file, I removed all the properities I didn't want, leaving only two... "interval" and "callFunction" (which was originally named "changeFunction"). Then I removed all the unnecessary code that involved checking for the existence of directories and getting directory listings and such. Then I tried to compile:
Problem #1 - no java compiler
Coldfusion includes the Java Runtime Environment (JRE), but not the SDK, which is what you need to compile things. The solution here was simple - download the JDK from http://java.sun.com. Make sure you get the same JDK version that coldfusion is running - in my case, 1.4.2 (technically, 1.4.2_05_b04, but Sun only made 1.4.2_10 available, the latest release, and that seemed to work).
So I got it installed and tried to compile. And I got 24 errors. I didn't even realize there were that many lines in the code! Most of them said "Can't resolve symbol" or "Unable to resolve symbol" or something. I did a little googling and found out that I needed a class path.
Problem #2 - defining your class path
Well, the java compiler is kinda stupid, and doesn't know where all the tools on your system are located, so you have to tell it by setting a classpath environment variable, or putting the classpath into the command line. To figure out what jar files had to be included, I looked at $CFHOME/gateway/src/build.xml and saw 4 jars that had to be included, so I set my path like this:
PLATFORM NOTE: I'm using Linux, and my shell is bash. I'm not here to tell you how to set environment variables in UNIX shells or windows. If you need help properly setting environment variables, you might find this classpath tutorial helpful.
export CLASSPATH=".:/root/j2sdk/lib/tools.jar:$CFHOME/lib/cfusion.jar:$CFHOME/lib/log4j.jar:$CFHOME/runtime/lib/jrun.jar:$CFHOME/gateway/lib/examples.jar"
A couple important things to note:
- each entry in the classpath is separated by a colon, and there should be no colon at the beginning or the end of the classpath
- the first entry should always be a period, telling java and the java compiler to always look in the current directory.
- The classpath must always include the tools.jar file, or pretty much nothing will work! I forgot this part initially and it took me a bit to figure it out.
Okay, so my classpath is now set and I tried again.
Problem #3 - weird bug involving abstracting and overriding the accept() method
The DirectoryWatcher gateway example is extends the EmptyGateway class - but it also implements the FilenameFilter class. Since i'm not doing any work with filtering filenames, I had to remove the "implements FilenameFilter" from the public class declaration in the source file.
After doing this, I compiled successfully. Yay! The documentation says to put it into a jar file and then place it in the gateway lib directory.
Worked fine and I moved it to the appropriate lib folder, and restarted Coldfusion. Consult the CF documentation for the appropriate folder, it's different if you're using CF standalone or j2ee.
So I then logged into the CF Administrator to add the Gateway Type.
Problem #4 - full java class? What the heck does that mean?
I had no idea what to put here. The documentation didn't help either, so I looked at the DirectoryWatcher class in the CF Admin, and it said the class was "examples.watcher.DirectoryWatcherGateway". I looked at the source code for that class, and saw "package examples.watcher" and figured that this must be where it came from. So I changed it from "examples.watcher" to "package com.opensourcecf.gateways", then moved my files around a bit, so that my source code path was $CFHOME/gateway/src/com/opensourcecf/gateways/SimpleGateway.java
I then recompiled without error again, copied it to the gateway lib folder, and restarted coldfusion again.
I was able to successfully add the Gateway Type using the full java class "com.opensourcecf.gateways.SimpleGateway"
What fun!
I'll be releasing my SimpleGateway class as open source, as people might find it useful, and when I do (maybe tomorrow), I'll blog about it at www.opensourcecf.com and I'll post a direct link to the blog entry here.
You are not logged in, so your subscription status for this entry is unknown. You can login or register here.
Steps I took to create the Event Type:
1. Download simplegateway.zip
2. Unzip simplegateway.jar to C:\CFusionMX7\gateway\lib (Non-J2EE edition of ColdFusion)
3. Attempted to add Event Gateway Type as:
Name: SimpleGateway
Desc: Simple Gateway
Class: com.opensourcecf.gateways.SimpleGateway
Timeout: 30
Error received:
Error creating gateway type.
Unable to find or load Gateway class com.opensourcecf.gateways.SimpleGateway
Any thoughts?
Thx,
http://www.jmpj.net/jason/index.cfm?mode=entry&entry=9172BDDE-CF1D-76B8-A792B315CE369DFB
It watermarks some text onto an existing image, randomly adjusting the height above the baseline.... uses java. Creates the img then calls it via a cfm that uses to return it (and theoretically delete it).. the value itself is stored in a session variable on the server.
http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=1&catid=21&threadid=1201832&enterthread=y
Now I just need to figure out how to change some of the control characters that the java serversocket class uses.
To check the JRE that colfusion is running, go to Settings Summary in the CF admin and look on the line that says Java Version.
If you need to change the JRE that CF runs, I would stop the CF Server, rename the CFusion/runtime/jre folder to something else like jreOLD (in case you need it later), and then copy over another jre folder (e.g. C:\j2sdk1.4.2_15\jre, assuming you've installed a JRE there) to replace jreOLD. Restart CF, check in the Settings Summary to make sure it's running the new JRE, and that's it.