technology

Dude, where’s my class?

Have you ever been stuck in a situation where you needed to find out where a particular Java class was loaded from? While this may not be the kind of problem the average CFer faces, I’m sure there are many gurus who can attest that they’ve been burned with issues of this sort. Robi Sen recently posted a bit of Java code to help solve problems like this, and reminded me of a time just a few months ago when I had to chase down a bizarre bug that turned out to be rooted in exactly this kind of JAR file hell.

On the ColdFusion team, we have a fairly rigorous checkin/build/test process. Every time anyone checks something in to the source control system, the build machine gets it, attempts to do a full build and runs a series of automated regression tests against it, just to make sure that nothing obvious has been broken. Those who break the build have the dubious honour of being named beer boy/girl, until someone else breaks the build, and claims the crown!

This has happened to me several times and, on most occasions, the problem was obvious, embarrassing, and easily fixed. However, in this particular case, I just could not figure out what was going on - I’d made changes to a couple of classes, with class A relying on a new method that I’d introduced in class B, but the build machine would constantly fail, with an error message which made it appear as though the new method on class B just did not exist. The build worked on my machine, and on other engineers’ machines, but constantly failed on the build machine.

It was Rupesh who eventually suggested that, perhaps, class B was getting loaded from somewhere other than it was supposed to be. As matters turned out, he was right. There was a dead JAR file that someone had placed on the build machine with a very old version of class B; the build machine was trying to build against that, rather than the newer version which I had checked in. Once the dead JAR file was removed, everything went through OK, and my beer boy crown passed on to the next hapless build-breaking engineer.

This bit of detective work was made possible by some interesting, albeit not very well known, Java APIs. All Java classes are defined, self-referentially, as instances of the class java.lang.Class. The java.lang.Class instance for a specific Java class can be loaded using java.lang.Class’s forName method. Every class maintains an object called ProtectionDomain, which defines the security access rules for the domain which that class belongs to. ProtectionDomain, in turn, maintains a CodeSource object that points to the location from which the code for that domain was loaded. The one gotcha to keep in mind is that the CodeSource object will be null for code which is loaded by Java’s bootstrap* classloader.

So here’s a bit of CF code which uses these APIs:

<cfset codeSource = createObject("java", "java.lang.Class").forName(url.classname).getProtectionDomain().getCodeSource()>
<cfif not isDefined("codeSource")>
<cfoutput>Code source is not defined; <b>#url.classname#</b> is probably being loaded by Java's bootstrap classloader.</cfoutput>
<cfelse>
<cfoutput>The class <b>#url.classname#</b> was loaded from <b>#codeSource.getLocation().toString()#</b></cfoutput>
</cfif>

Just pass your classname in (be sure to get the uppercase/lowercase characters right! Java’s not as forgiving as CF) with the classname URL parameter, and this little code snippet will tell you exactly where the application server loaded the class from.

There is one caveat to keep in mind, which can be good or bad, depending on where you’re coming from. The example that I’ve provided will show where a class is loaded from, from the perspective of the calling code’s classloader. 99% of the time, this is exactly the behaviour you’ll want, but for those with more advanced requirements, you may want to drop this code into a more appropriate location. This is an important consideration, since Java does allow parallel classloaders, which may load the same class from different locations. All application servers adopt this approach, since it is mandated by the JEE specifications. Sounds abstruse? Ignore this little detail then, it probably doesn’t matter to you anyway.

For those strange times when you have to debug a problem on a production system, or want to make sure that you’re using exactly the same classpath as your application server, you may want to try the approach that I’ve outlined. I hope that it will help you as much as it helped me.

Update: As Dan points out, Robi’s intention was quite different from mine - his code was written to list all classes in a given package, not to find where a class was loaded from.

* The Java bootstrap classloader is the mother of all classloaders, which loads up the Java core libraries. All application servers establish their own byzantine classloader hierarchies under the bootstrap classloader; I’ll navigate that labyrinth another time. For the curious, this theserverside.com article, although a bit dated, will give you an idea of what’s involved.

code
coldfusion
java
technology

Comments (3)

Permalink

Sneak Peek: Scorpio Server Monitoring

Just for all you folks who couldn’t make it out to MAX - here’s a peek at what Scorpio may be offering up for server monitoring. This is the presentation I gave at MAX, with voice over, but missing, alas, the live demos. It may take a little time to load because of all the audio, so do be patient.

Unlocking the ColdFusion Server Black Box

Take a look, and leave comments here in case you think there’s anything big that we’re missing.

Disclaimer: This feature is still under development and is subject to change. Consider this presentation to be a just a preview of something that may make it into Scorpio.

coldfusion
technology

Comments (9)

Permalink

WTF, IBM sues Amazon???

So I fired up my feed reader and started poring over posts from days gone by that I’d missed, and what do I find? Via Tim Bray, IBM suing Amazon over patent infringement. And what might the infringed patents be?

  • Presenting Applications in an Interactive Service
  • Storing Data in an Interactive Network
  • Presenting Advertising in an Interactive Service
  • Adjusting Hypertext Links with Weighted User Goals and Activities
  • Ordering Items Using an Electronic Catalogue

WTF???

If this isn’t an argument for patent reform, I don’t know what is.

biz
internet/society
technology

Comments (2)

Permalink

MAX 2006 wrapup

A little late, I know, but the jetlag has finally cleared enough to allow me to write coherently… Yep, just in time for me to head back to Bangalore and go through this all over again!

As many will know by now, we showed off a bunch of features coming in ColdFusion 8 aka Scorpio. Prayank covered image manipulation, Rupesh talked about CF-.NET integration, and I got to show off server monitoring. For those of you who couldn’t make it, we did record our presentations prior to heading out; I’ll send a link to those once I know where they’re being hosted. If you just can’t wait for those, check out some of the liveblogging summaries that Rob and Ray (thanks, guys!) put out from the sessions:

  • Image Manipulation - Ray, Rob
  • Server Monitoring - Ray, Rob
  • CF-.NET integration - Ray, Rob

As is generally the case with the CF team, the developers presenting features are those who worked on them, so if you have any specific questions of these features, head on over to Rupesh’s or Prayank’s blogs (or mine, but you know where that is!) and leave us comments.

The one big MAX announcement that I think is going to be really interesting is the Apollo platform. Various technologies have attempted to provide simple network-distributed applications in the past, and all of them failed, though some do still linger on - Java WebStart (still alive and kicking), Zaplets (dearly departed), Droplets (still around, it would seem). Then, of course, there are newer contenders like the Yahoo desktop widgets; while that engine is pretty interesting, it doesn’t yet match Apollo for features and, for the moment, seems aimed towards more restricted one-off applications.

I think Adobe has got it right with Apollo - the programming environment is simple and familiar (JavaScript, HTML, Flex, PDF, all of which CF plays with nicely, of course), and Adobe owns what is arguably amongst the most powerful software distribution mechanisms on the planet, the installed base of Flash player users. You’ll be seeing Apollo applications in the enterprise pretty soon, I”m sure; but I’m equally certain that you’ll be seeing a lot more of them out in the wild, on the public web. This is one client technology you don’t want to miss out on.

coldfusion
technology

Comments (4)

Permalink

Crawling on the Map: MAX 2006

Apologies all for the long silence - after I got back from a perfectly lovely holiday in Goa, work got pretty busy, especially with all the last minute preparations for MAX.

I arrived in Las Vegas last night. A little early, perhaps, but those of us who are presenting from the CF team decided to get here a day before MAX kicks off so we could beat the jet lag in time for our sessions. Being a night owl is great in Vegas, I know, but having my mind shut down thinking it’s time for bed won’t be so good when I have to deliver my session, Unlocking the ColdFusion Server Black Box. For those of you who are here, do attend it if you can - I’ll be previewing some new CF tools, and I’d love to get your feedback.

The best part about this for me is that I’ll finally be able to move some of the stuff I’ve been working on for Scorpio out of stealth mode. I’ll be writing more about it here, so those of you can’t make it out to MAX can get an idea of some of the things the CF team has been throwing in the pot for Scorpio.

I’ll be at the reception tomorrow evening, of course, so if you’re here, do come by and say hello.

coldfusion
technology

Comments (7)

Permalink

HOWTO: Call CF from the command line

Sean put up his wishlist for CF recently, and one of the interesting things he was wishing for was the capability to call CF from the command line.

The thing is, you can already do this, and fairly easily. Let’s start by getting the right tool for the job - go pick up cURL, a tool for invoking URLs from the command line. Do note that if you choose to download the HTTPS-enabled version of cURL, you will need to also get the libeay.dll library for SSL support from OpenSSL.

That’s really all you need. You can invoke cURL like so: curl (CFM template URL). The output of the CFM is printed to the stdout, which means it will show up in your DOS window/UNIX shell/whatever. Easy, huh?

To invoke a CFC, you’ll have to use the CFC HTTP invocation syntax, which is simple enough:

http://(hostname):(port)/(context, if JEE deployment)/(path to CFC)?method=(function to invoke)&(argument list)

Responses from CFC functions are returned in WDDX format, unless the function returns XML, in which case the XML is returned as-is. Oh, and do make sure you tag your function with access=remote so that CF will allow remote calls to it.

For example, to invoke a function called echo, which takes an arguments input1 and input2, on a CFC my.application.callme, on a standalone CF deployment, you could do this:

http://myhost/my/application/callme.cfc?method=echo&input1=yodel&input2=hey

For those who think all this is just too hard (yeah, right!), here’s a simple shell script that will do the job of invoking a CFC - edit it to change your serverroot, then invoke it at will, passing in the CFC, function and argument list (in the form arg1=val1&arg2=val2).

serverroot="http://localhost:8500/"

callto=`echo $1 | sed -e 's/\\./\\//g'`
cffunction=$2
args=$3

url=$serverroot$callto".cfc?method="$cffunction"&"$args

curl $url

For example, if your save your script as callCF.sh:

callCF.sh my.application.callme echo input1=yodel&input2=hey

Apologies to DOS users - the scripting that I have done, I’ve done on UNIX systems. Even when I’m forced to use Windows on the desktop, I always have Cygwin installed so I have all those great UNIX command line tools handy.

Now I hear you thinking - do we really have to have a server running to make all these invocations? Couldn’t we have a nice lightweight runtime that can be invoked on the fly? In theory, yes, of course we could. In practice, absolutely not - CFMX was built on the assumption that it would run within a JEE application server. Ripping out, and rebuilding, all the plumbing would be a prohibitively expensive task.

Well, there’s at least one wish fulfilled that we can all talk about - if only the others were as easy! I cannot, alas, yet tell you how many more of Sean’s, and others’, wishes will be granted for Scorpio… But rest assured, we’re paying attention. And some of those wishes, well, they’ve already been granted.

Update: Dopefly opines, as Sean does, that a gateway would provide for more secure invocation. I don’t entirely agree with them - this really comes down to where you choose to put your security, in a gateway, or in a CFC. It could easily be embedded in a CFC by checking that the CGI.SERVER_NAME is localhost, or by ensuring that the IP address of the caller, CGI.REMOTE_ADDR, is in a whitelist of IP addresses allowed to invoke the CFC.

code
coldfusion

Comments (7)

Permalink

Introducing Rupesh “Mad Scientist” Kumar and Hemant “Pointy Haired Boss” Khandelwal

Rupesh, of Coldfused? fame, is finally back to blogging, after having cranked out a final version of the CFThread POC. He’s one of the smartest guys I know, and is at least partially to blame for hiring me to the CF team… ;-)
Check out his entries on Handling J2EE Sessions with Cookies Disabled and JRun Threadpool Settings.

Like Hemant (get a blog, dude!) Khandelwal, the manager on our team, he came to Macromedia from Pramati, an Indian software product company that set out to create a JEE application server. While the Pramati technology is great stuff, it proved difficult for them to make it in a market already crowded with JEE application servers, especially when going up against the likes of IBM and BEA. During his time there, Rupesh worked on a lot of the hard security problems, so whenever we have to deal with things like HTTPS and certificate management, he’s our go-to guy.

And speaking of Hemant, he’s no slouch in the technical department either - he was responsible for the first commercial EJB 2.0 compliant container, in the Pramati JEE server, and has served on the EJB specification committee. While he does enjoy whipping us lazy louts to get some work done, I know he misses coding…

coldfusion

Comments (2)

Permalink

I was nuked by Ray Camden

Artist’s impression of Ray nuking Ashwin ;-)

anything else
coldfusion
whatever

Comments (1)

Permalink

Quack!

If it talks like a duck and walks like a duck, then it must be a duck… and, apparently, it’ll waddle a good deal faster than a turkey, or any other non-duck species.

I’ve been meaning to get to the subject of duck typing and performance ever since I saw Sean give his presentation at CFUnited. Unfortunately, the performance aspect of going duck was what caught most people’s attention; as Sean shouts out duck typing is not about performance.

I finally got round to downloading Sean’s source code and ran some tests of my own. Here’s the low-down - performance is affected only when the argument type or return type is specified as a CFC; if it is anything else, performance is about equal to the duck typed equivalents. If you’re typing arguments and return values to structs, arrays, strings, numbers, whatever, duck typing will not give you any performance gains. Apologies all if I’m repeating what’s already been pointed out; I searched around a bit and couldn’t find anyone else commenting on this particular detail.

CFC type checking is always going to be more expensive than checking any other type, since we need to jump through many of the same hoops as we do during createObject() to actually resolve the path to the CFC template - is the path to type being checked relative or absolute? Is it referenced via a mapping? Is the type being checked a supertype of the type passed in? You get the idea; evaluating these kinds of complex relationships is expensive.

So do duck type if your design calls for it, or if you’re having serious performance problems with code that checks for CFC types. Otherwise, make like a monkey and code!

Update: You can download the code I used for testing here. It’s identical to Sean’s code, with the exception of a new typedNative function in performance.cfm, which is used to test for “native” types, i.e., Struct, Array, whatever.

code
coldfusion
technology
whatever

Comments (3)

Permalink

To boldly go where…

… no server (or language, or platform, or all of the above!) has gone before?

Much fuss has been made over CF not being an enterprise platform. All too often, it would seem, we’re the poor kids who get the ‘lite’ projects. Why is this?

I will concede that some of the fault lies with the product. There are long standing requests such as CFC serialization that have yet to be addressed. There are performance issues that have been found with CFSWITCH, string concatenation and other areas of the server.

So I’d like to ask all of you - what’s your number 1 problem that stops you from being able to sell CF up to your management/customers as an “enterprise” grade solution? Leave your comments here, and I promise they’ll be looked into.

At the same time, I think we as a community have some work to do as well. How do we change the impression that CF is not an enterprise platform? There is a problem to CF being such an easy language to learn, with so much power packed into individual tags; it’s just as easy to abuse that power as it is to use it. Could CF provide more checks and balances to ensure that this does not happen? Perhaps, but definitely not in every case.

So do start applying those best practices and numerous frameworks (and un-frameworks!) in your projects. Read the presentations Sean’s put up, Ben’s resources page, and the numerous CF blogs dealing with this stuff. I’m the last person to claim that the application of these best practices and patterns are easy to understand the first time round; but as you get into them, I think you’ll find that they become a habit, an integral part of the way you design and code.

On an (un)related note, the crew of the good Starship Enterprise celebrated their 40th anniversary this weekend past - happy birthday, Star Trek!

coldfusion
technology
whatever

Comments (25)

Permalink