There's not a ton of information out there on using ColdFusion Components from within Java, so I wanted to document a problem I was having. I'm in the process of evaluating using Drools as a Rules Engine to use within ColdFusion. One of the problems you face in using Drools, is you need to represent your CFC in a way that Drools can work with it. This means you need to do a couple of things:
Setting all this up was pretty straight forward.
The problem that I was running into, was I could never successfully call the "setter" on a CFC object that was created dynamically using the "accessors='true'" option on my CFC.
Here was my very simple CFC:
component output="false" persistent="false" accessors="true" { property name="name" type="string" ; property name="age" type="numeric" default="-1" ; property name="valid" type="boolean" default="true" ; }
The problem is, every time I'd try to call the setter on my dynamic proxy item, I'd see an like "java.lang.ClassCastException: coldfusion.runtime.TemplateProxy".
The Java interface I was using, looked like this:
public interface ApplicantInterface { public String getName(); // automatic setters, return "this" which is a reference to the proxy object public void setName(String name); public int getAge(); // automatic setters, return "this" which is a reference to the proxy object public void setAge(int age); public boolean getValid(); // automatic setters, return "this" which is a reference to the proxy object public void setValid(boolean valid); }
Accessing the getters() worked as expected, so I knew there was something in the way the setters were working that was causing a problem.
After dumping out the metadata for my CFC, I finally discovered the issue.
When CF10 automatically creates setters, the return type on the objects is not void, but instead is a references to the CFC itself.
There are two ways to resolve the problem:
I decided to use option #2. Here's what my final interface looked like:
public interface ApplicantInterface { public String getName(); // automatic setters, return "this" which is a reference to the proxy object public coldfusion.runtime.TemplateProxy setName(String name); public int getAge(); // automatic setters, return "this" which is a reference to the proxy object public coldfusion.runtime.TemplateProxy setAge(int age); public boolean getValid(); // automatic setters, return "this" which is a reference to the proxy object public coldfusion.runtime.TemplateProxy setValid(boolean valid); }
In order to use a return type of "coldfusion.runtime.TemplateProxy", you'll need to make sure to add the cfusion.jar to the classpath when compiling your code. For example:
javac -g -cp {{ColdFusion 10 Install Folder}}\cfusion\lib\cfusion.jar -d ./bin/ ./src/*.java
Hope this helps someone else in the future!
There was some disturbing news yesterday—and I'm not talking about the death of Steve Jobs. The "Olson" time zone database was taken offline. While the immediate impact may not be felt, this is a very important open project and shutting it down is potentially going to cause a lot of problems.
For those that don't know, the time zone database has been maintained by a group of volunteers over the years and hosted at National Institutes for Health and contains historical, present day and known future information on day light savings changes around the world. This database is used by a huge of array of platforms to keep accurate time—Java, Unix, *nix, smart phones, etc. If you have an app that can tell you the current time in another location, there's a good bet it's based on this time zone database (either directly or via the underlying language's platform.)
Here are some good articles with more insight:
As many have already commented on, I'm not sure how this law suit can hold up since historical information can not be copyrighted. However, the law suit will have an impact—especially for applications in use by locations where the day light savings is in frequent flux.
The code base I work in every day includes a few external development tools that are included in our source code. We include the tools in the source code, because it's the easiest way to ensure that every developer has access to the tool and can run them quickly.
However, one disadvantage to include external development tools into your Eclipse projects is they can slow down searching your enclosing projects because they include files you generally don't really want to search. If you have a library such as "MXUnit" in your source, that adds hundreds of files that would be added to the search which you don't want.
One way you can avoid searching specific folders is to set up a "Workspace" and stick to searching workspaces. This works great, but requires that you maintain your workspace and keep it up to date. Our code base has thousands of files and hundreds of folders over several different projects, so I just find maintaining the workspace a little more tedious than I'd like.
I much prefer using the "Enclosing projects" option in Eclipse, because it searches the files in your active project. I find these is much easier than changing the workspace when I'm looking at files in a different project. So I did a little research this morning to see if there was an option to exclude folders/files from showing up in the search by default.
Turns out Eclipse has a feature called Derived resources:
Many resources get created in the course of translating, compiling, copying, or otherwise processing files that the user creates and edits. Derived resources are resources that are not original data, and can be recreated from their source files. It is common for derived files to be excluded from certain kinds of processing.
When you mark a folder or file as derived, it's excluded searches. The caveat is Eclipse assumes derived resources are probably compiled resources, so if you try to edit a derived file you will be warned that the file is derived. However, since these are external tools that I'm not needing to regularly update, this behavior is fine—and actually a nice reminder.
To set a folder as derived:
This has done the job nicely. I've been able to exclude several hundred files from showing up in my searches that I really don't care about!
NOTE: Generally derived resources are typically not files you'd keep in a repository, because they can easily be rebuilt from source code. While I had no problems setting a folder already in my SVN to derived, it's possible some source control plug-ins might treat a derived resource as being "ignored".
I've been working on migrating to Eclipse v3.6.1 x64, but was having a ton of issues getting Subversion/SVN support working in Eclipse. I prefer using Subclipse, so it was my goal to get that up and running because I'm used to the interface.
I originally tried using SVNKit, because I wanted to use native libraries. However, when I tried to use the SVNKit connector, every single time an SVN operation would occur it would prompt me over and over for my credentials—like it was saving them (although it was updating the .keystore.) After getting frustrate with this, I decided to just use the JavaHL libraries.
If you're using Eclipse 32-bit, then everything you need is included with the distributed versions of Subclipse. Since I'm using the 64-bit version of Eclipse, I needed to download Slik's Subversion v1.6.16 (x64). So, I closed down Eclipse and install the 64-bit client. I verified that everything was working correctly by running the javahltests.jar.
However, after restarting and configuring Subclipse to use JavaHL, I started experiencing issues with Eclipse hanging up. I'd constantly get messages like "Building workspace"—which would stay at 0% and never progress. Switching back to SVNKit was working, but the constant credential checking was driving me crazy. So, after lots of researching, I finally found a thread on authentication issues on the SVNKit mailing list. Turns out I am using NTML and Basic authentication on our server and that was causing an issue with SVNKit.
The fix is to edit your eclipse.ini file and add this line somewhere after the "-vmargs" line:
-Dsvnkit.http.methods=Digest,Basic,Negotiate,NTLM
Depending on your configuration, you may need to tweak the order of the methods, but as soon as I restarted Eclipse with this line in my eclipse.ini everything started working like I expected.
I'm working on some "star rating" code and I really wanted to round numbers of to the nearest fraction. While the math is really basic, my math skills are rusty and this took me longer to solve than I care to admit. So I thought I'd just blog the solution for anyone else that might find it useful:
round( value/fraction ) * fraction
Like I said, it's very basic math but is very handy when you want to round to something other than to the closest integer.
This morning started off to a rough start. I came in to realize the commit of a merge I made at the end of the day yesterday had failed. Whenever I would attempt to commit the merge changes, it would go through the entire process and then finally fail with a error message of:
org.tigris.subversion.javahl.ClientException: Working copy text base is corrupt
After trying a "Cleanup" and several other steps to rectify the problem, I finally did hit Google to try and find a solution. I came across chris' subversion checksum mismatch - easy workaround which offered several various solutions to the problem.
I tried several of the solutions, but wasn't haven't much success until I came across Michael Sparer's comment:
Thanks for the explanation, which shed some light on how svn manages its working copy. My problem seemed to stem from a bogus file under .svn/text-base, which didn't match the file actually on the server.
- server file (.../x.java): OK
- orig copy from server (.svn/text-base/x.java.svn-base): BOGUS (not same as server)
- checksum (in .svn/entries): matches server, but not server copyIf I can make the bogus copy match what's on the server, then it will also match the checksum, and everyone will be happy.
What I did (i'll call the working dir with the corrupt file "orig-dir":
1. Fresh checkout of svn dir matching orig-dir into /tmp/blah
2. Copy /tmp/blah/.svn/text-base/x.java.svn-base into orig-dir/.svn/text-base
3. Check in successfullyI wish svn would let you refresh a given file from the server...maybe there's a command and I just haven't found it or my svn is too old.
In the end, this ended up being my problem as well. The copy of me .svn/text-base/filename.ext.svn-base was out of sync with the actually copy on the server.
To resolve this, I checked out a clean copy from the server to a tmp folder, then I just replaced the copy in my working folder. After doing this, I was able to check in the file without incident.
NOTE:I could have just wiped my local copy altogether, but I wanted to know the root problem incase it every happens again. Since I have a pretty large repository it takes a while to checkout from SVN, so at least know I have an option to try if I ever run into the issue again that won't require me checking out the entire working directory structure.I also noticed I had a copy of the template in the .svn/tmp/text-base/ folder. I made a copy of this file and then removed the file this directory before committing. I'm not sure if this step is necessary, but I wanted my local working copy to mirror as closely as possible a fresh working copy.
Recently after installing a fresh copy of Eclipse 3.4 on my PC, I ran into an issue with the "Open Resouce" dialog ([CTRL]+[SHIFT]+[R]) where it was showing all my SVN files. Installing Subclipse is supposed to make the Eclipse IDE automatically hide the .svn-base files from showing up (via the "Team" interface) but it wasn't working out for me.
Turns out there was a very easy solution to this problem—just right click on the project and choose "Close Project" from the menu. After the project closes, just right-click on the project and select "Open Project." This should reinitialize all the settings on a project and appears to registered the handling of automatically hiding the .svn-base files.
An alternative, would be to add the find your org.eclipse.ui.ide_3.4.*.jar (org.eclipse.ui.ide_3.4.2.M20090127-1700.jar) and then modify the plugin.xml file to include the filter "*.svn-base". I don't like this option because it requires you to change a JAR that could later be updated.
If you choose that route, close Eclipse and open the JAR with a Zip extraction tool. Next, search the plugin.xml for the text "<filter". There should be one filter tag:
I was looking for a way to programmatically refresh some specific folders in my workspace anytime I ran my ANT script. Eclipse provides several ant tasks that you can use for various purposes, once of which is the <eclipse.refreshLocal /> tag:
<eclipse.refreshLocal resource="MyProject/MyFolder" depth="infinite"/>
- resource is a resource path relative to the workspace
- depth can be one of the following: zero, one or infinite
However, when I first tried adding this task to my ANT script, I was getting an error that looked like:
BUILD FAILED
c:\path\folder\build.xml:85: Problem: failed to create task or type eclipse.refreshLocal
Cause: The name is undefined.
Action: Check the spelling.
Needless to say, I was pretty confused. So after some brief research, it turns out I accidentally running ANT outside of the Eclipse JRE. To fix this, go open up the External Tools Dialog (Run > External Tools > Open External Tools Dialog...) and make sure the JRE tab is set to "Run in the same JRE as workspace."
I'm not sure how that setting got changed, but I'm glad I found the fix. This also has sped up the first time execution of my ANT scripts.
We recently bought a Self-Signing Cert from Comodo through Tucow's Authors site. Through Tucows I was able to get a 3 year cert for $195—which is cheaper than a 1 year cert from either Thawte or Verisign.
I was expecting them to send me a cert via e-mail, but instead they install the certificate into the browser in which you purchased the certificate. From this point on Comodo doesn't offer any instructions on how to use the cert, so I had to do some research.
First, I'd recommend buying your cert using Firefox. If the cert gets installed into Internet Explorer, you need to jump through a bunch of hoops to generate the p12 file from the pvk format. Once you have your cert stored as a PKCS12 file, the steps for signing your Java Applet are pretty straightforward.
The instructions below show you how to sign an applet provided your personal cert has installed into Firefox. If you already have your p12 file, the you can skip to step 11(the directions use the filename of self-sign.p12 for the exported key.)
You should now see some output that looks like:
Keystore type: PKCS12
Keystore provider: SunJSSE
Your keystore contains 1 entry
[Alias], Jan 1, 2008, keyEntry,
Certificate fingerprint (MD5): hh:hh:hh:hh:hh:hh:hh:hh:hh:hh:hh:hh:hh:hh:hh:hh
The [Alias] is a string that might be look like a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx) or it could just be string of various text. The alias will be the part of the text up to the first comma before the date.
I highly recommend creating an Ant build.xml script for compiling and signing your JAR. The biggest benefit is once you get it set up, there's nothing manual you need to do.
I've been working on a Java applet that can get images from the user's clipboard or take screenshots of the user's desktop and upload them to a server via HTTP. The last piece of the puzzle was to make sure I could access the task methods via JavaScript, as the interface will most likely be driven by HTML.
I've been using a self-signed cert to sign the Java Applet so that I can access the user's clipboard and take the screenshot. All of this was tested and working extremely well from if I used the Applet UI. However, as soon as I would try to invoke one of the sandboxed functions from JavaScript the applet started throwing the error:
AccessControlException is thrown: access denied (java.awt.AWTPermission accessClipboard)
I tried a number of things to get around this problem. I thought it was something I was doing wrong when I was signing the applet (since it was working fine from within the Applet's built-in UI controls.) After playing around with the cert signing process and getting no where, I finally came across the post JavaScripting in Applets - Getting Out of the Sandbox where a comment from Stéphane Bury pointed me to a solution.
public static void doSpecialWork(String param1){ final String fParam1 = param1; java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { // put the code of your method here ... ... return ""; } }); }
My final solution was to write a command() method which I can use to trigger off the internal privileged methods:
/** * The method to invoke from JS to perform the privileged methods--which throw * security errors if you try to access them directly. * * @param command - the command you want to perform (clipboard, screenshot, upload) */ public void command(String command){ final String cmd = command; java.security.AccessController.doPrivileged( new java.security.PrivilegedAction(){ public Object run() { // execute the privileged command executeCommand(cmd); // we must return an object, so we'll return an empty string return ""; } } ); }
As you can see the method is very basic, it just passes the command it received to a private method which actually executes the command. Now I can access any of the privileged methods in my applet with this little helper method.
One thing I rarely ever do in Java is program anything that requires a desktop UI. If I'm doing any Java programming, it's generally server-side related. Recently that changed when I began working on a Java applet that allows users to upload images (screenshots) in their clipboards directly to the server.
Building the basic applet was pretty straightforward. Even signing the applet (so you can actually query the operating systems clipboard) is pretty straightforward—made even easier once I created an ANT build script.
The applet was progressing nicely, well that's until I tested things on the Mac.
As I mentioned early I've been working on a SVN post-commit script. We've got a SVN repository that will be modified by several remote developers and I really need to keep an eye on this repository and I need to closely monitor changes to this repository.
There are two major functions that I needed in my post-commit script:
There are an abundant of examples showing off how to do this in various *nix flavors, but I couldn't find any good Windows-based solutions that didn't require Perl to be installed on the server. That led me to create the following post-commit.bat script.
I've been working on a post-commit hook for our Subversion install and was running in to a number of issues. The post-commit.bat file would run fine from command line, but I just could get things to work as I expected from SVN. After much debugging and scouring Google for answers, I've found a few tips that will hopefully help you to troubleshoot your own SVN repository hooks.
This was the biggest issue I was running in to, because I was expecting the my script to be able to find any programs in my %PATH% statement. That's the main reason my scripts were working fine from command line, but were breaking when executing from my SVN hook.
Whenever the topic of my employment comes up, everyone's first reaction when I tell them I work from home is: "Wow, that must be really nice!" While working from home definitely has some benefits, it has some cons.
As Cameron Childress mentions in his post on Coworking in Atlanta, the two hardest things to adjust to are the lack of socialization and self motivation—both are issues Cameron and I have talked amongst ourselves about in the past.
I recently posted about a new open source Java project called AntiSamy—which allows you to protect your websites from XSS hacks. I also promised that I'd soon show you some code examples that show you how you can use AntiSamy within ColdFusion.
I've only tested this code under ColdFusion 8. It should theoretically work on any ColdFusion installation, provided you're using a JDK version that supports the compiled version of the AntiSamy code (which is compiled to Java v1.5.)
Before you can actually use AntiSamy, there are a few quick steps you need to make.