[Looking for Charlie's main web site?]

Resources for Getting Started with CFEclipse

Note: This blog post is from 2006. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
As CFML developers contemplate (or make the move to) CFEclipse, which is a CFML plug-in for the open source Eclipse editor, they will naturally have questions. Does it support the features I want? What does it add? How easy is it to make the transition?

I think most developers will find that it does what they want (tag insight, tag help, code snippets, and more), and it will do still more than they may expect. Still, it may trip some up at first as they make a transition. Changing editors is always a challenging proposition, just because we become so used to our current editor. Still, more and more developers are making the switch, and you may want to learn more about it.

Challenges Getting Started

A challenge is that there's not too much in the way of getting started docs at the CFEclipse site, http://www.cfeclipse.org/. But there are ample other resources out there to help with that.

Another challenge is that one has to get into using Eclipse itself. That can be a little daunting, but it need not be a show-stopper for you. The truth is that you really can ignore a lot of what other developers (like Java developers) would do with Eclipse, and you can focus on it just being a CFML editor. There are some quirks and differences.

Finally, the tool itself has evolved, so some of the things that may have annoyed early adopters have indeed been fixed, and more and more features have been added, thanks to Mark Drew, the project lead.

So with that introduction, I want to point out that there have been various resources (articles, resource pages, and more) put together on getting into CFEclipse, and I'd like to point to some of them here, as I've found no single page yet that does that.

CFEclipse Articles in the CFDJ

First, there have been some articles in the ColdFusion Developer's Journal:

CFEclipse: The Developer's IDE, Eclipse For ColdFusion, Aug 2005, by Simeon Bateman and Spike Milligan
http://coldfusion.sys-con.com/read/48235.htm

CFEclipse for ColdFusion Developers, Jan 2006, Rob Rohan
http://coldfusion.sys-con.com/read/167971.htm

Making the Switch to CFEclipse to Write ColdFusion Code, April 2006, by Jeff Houser
http://coldfusion.sys-con.com/read/206261.htm

Robert Blackburn's CFEclipse Article Series at FusionAuthority

Next, Robert Blackburn has done a series of articles on the FusionAuthority site:

Introducing: CFEclipse Features
http://www.fusionauthority.com/News/4610-Introducing-CFEclipse-Features.htm

CFEclipse CFExplained Part I
http://www.fusionauthority.com/Techniques/4599-CFEclipse-CFExplained-Part-I.htm

CFEclipse CFExplained Part II
http://www.fusionauthority.com/Techniques/4607-CFEclipse-CFExplained-Part-II.htm

Introducing: CFEclipse Features
http://www.fusionauthority.com/News/4610-Introducing-CFEclipse-Features.htm

CFEclipse Features: Task List
http://www.fusionauthority.com/Reviews/4619-CFEclipse-Features-Task-List.htm

CFEclipse Features: Code Folding
http://www.fusionauthority.com/Reviews/4631-CFEclipse-Features-Code-Folding.htm

CFEclipse Features: Tag Insight
http://www.fusionauthority.com/Reviews/4633-CFEclipse-Features-Tag-Insight.htm

CFEclipse Features: Local History
http://www.fusionauthority.com/Reviews/4648-CFEclipse-Features-Local-History.htm

I couldn't find any one page on the FA site (or on the web) with a link to all of Robert's articles, though some of them do show a progressively building list of links at the bottom pointing to the previous articles. I do think the list above is all that there have been so far, but I welcome hearing from anyone who knows otherwise.

I'll also point out some other CFEclipse articles that are on the FA site (thanks, Judith, for pointing them out in comments below):

CFEclipse: A Community Affair: An Interview with Simeon Bateman, Project Manager by Judith Dinowitz
http://www.fusionauthority.com/Community/4534-CFEclipse-A-Community-Affair.htm

Test-Driven Development with ColdFusion Part III: Integrate Your Tests into CFEclipse Using CFUnit-Ant by Robert Blackburn
http://www.fusionauthority.com/Techniques/4583-Test-Driven-Development-with-ColdFusion-Part-III.htm

Nathan Strutz CFEclipse Resource Page

Nathan Strutz has also created a CFEclipse Intro and Resource page (FAQ) at:

http://www.dopefly.com/projects/cfeclipse.cfm

Mark Drew's CFEclipse Videos

Finally, Mark Drew, who is leading the CFEclipse project now, has done a set of videos available as podcasts:

http://www.markdrew.co.uk/blog/index.cfm/2006/8/12/CFEclipse-Podcasts

Still more?

I'm sure there are still more resources, and perhaps some are better suited to helping folks get started with just understanding CFEclipse and Eclipse from the perspective of a CFML developer making the move from, say, Dreamweaver, CF Studio, HomeSite/HomeSite+, or something else.

I really look forward to hearing from others with more/better resources.

PS I should also point out that another motivation for getting into Eclipse as a CFML developer, if not also CFElipse itself, is that the FusionDebug CFML Interactive Debugger is built atop Eclipse. I've done a series of entries on the topic:

http://carehart.org/blog/client/index.cfm/fusiondebug/

Reloading CF web services programmatically, using the CF7 Admin API

Note: This blog post is from 2006. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
I'm surprised to not see much out there about how to reload or refresh CF's cached WSDL proxy for calling a web service, at least programmatically using the new CF 7 Admin API. Perhaps it's because people have been tripped up, or simply haven't explored it. Either way, I'd like to offer here the code you need, and also point out some tips and traps.

Update for CF8: As an update to this entry from 2006, which is focused on CF7, I'll note that there was yet another approach that was added in CF8. Both still work and have their own value. More on the CF8 feature in my later blog entry. Still, the feature added in CF7 is important to understand, too, so please read on.

Introduction: Why You Would Want to

As background, someone reported having a problem calling a web service from CFML, and a solution suggested was that the person reload or refresh the web service using the CFMX Admin console (in the "Data & Services" > "Web Services" nav bar tab. There, you'll find any web services that have been called from CF (which is often a surprise to folks that they're tracked there). For each listed web service, there are 3 buttons and the middle one does a refresh (which means it goes and grabs the WSDL and builds a local java proxy stub, which is used when you then invoke the web service).

But one may then wonder how to do that programmatically, without having to open the Admin console. In CFMX 6.1, you could use the undocumented ServiceFactory, as I'll show below to those still using that. But since that's being deprecated, you really ought to learn the new CF7 approach.

The CF 7 Admin API Approach

As of CFMX 7, we are expected to use the new Admin API, a set of CFCs provided with CFMX 7, which offer a formal, secured API for accessing functionality otherwise offered in the Admin console.

So how would one do that to refresh a web service? Well, there is an extensions.cfc in the Admin API (a set of CFCs in the webroot's /CFIDE/adminapi/ directory), and it has a reloadWebService method that's just the trick. How did I know that? You can call the built-in CFC documentor by browsing the CFC directly:

http://<em>[servername]</em>/cfide/adminapi/extensions.cfc

Before you can call that, though, note that you do need to "login" to the Admin API by calling the login method of the administrator.cfc first. (Check out its docs to learn more.)

But to save you that effort, here's some code. (As always there are several ways to call a CFC and its methods (using CFINVOKE or CFOBJECT, or createObject either within CFSCRIPT or not), but here's at least one approach.):

<cfset createObject("component","cfide.adminapi.administrator").login("youradminpw")>
<cfset ws = createobject("component","CFIDE.adminapi.extensions")>
<cfset ws.reloadWebService(name="<em>webservicename</em>",path="<em>WSDLurl</em>")>

Note that you need to specify your own admin password in the first line, and in the last line you need to specify a web service name and its WSDL URL.

What's with this notion of passing in a web service "name"?

As you contemplate that code, you will certainly know what the WSDL URL is, since it's the same one you'd use in a CFINVOKE or CFOBJECT/createobject call of the web service itself. But what's the "name" requested here? Well, that can trip you up and it deserves further discussion, as it has several ramifications as I'll explain here.

The name is the name shown in the Admin console for the given web service. The trick/trap is that if you never open and change the Admin console entry for this web service, then the name will simply be the same value as the WSDL URL. But there's more to understand.

First, if you didn't know it, one can edit that "name" in the Admin console, and then one can even use that "name" as an alternative (or "alias") to the web service WSDL URL when invoking the web service from CFML. That's a whole separate subject which I've covered in user group talks in the past.

But assuming that no one has modified the web service name (or for reasons I'll explain in a moment, if you are not using such an alias name when you invoke the web service), then you can presume the name and WSDL URL to be the same. As an example, one could change the last line above to:

Getting Web Service Names Programmatically

Now may wonder, "can I get the web service name programmatically?" You can. But here's where it gets a little confusing. There is an available getwebservices method of the extensions.cfc. And according to the docs, you can either pass in the "name" of the webservice, or leave it off to get all web services. If we don't know the name, then we may think we'd want to use the latter approach. But I find that it doesn't quite work as straightforwardly as it seems.

First, I tried calling getwebservices() without a name:

<cfset createObject("component","cfide.adminapi.administrator").login("youradminpw")>
<cfset ws = createobject("component","CFIDE.adminapi.extensions")>
<cfdump var="#ws.getwebservices()#">

Sadly, it returned an empty dump as a result. Yet I had several web services listed in my admin console. Here's the thing: none had a name. I then renamed one of them (to "test"), and tried it again, and suddenly the call did return an array of structures (1, in my case) with the name and WSDL URL.

Hmm. So it seems instead that the getwebservices() ought perhaps instead be named getnamedwebservices(), since it only returns web services whose names have been changed (been given an alias).

Still, though, if I do pass in a name, as the docs suggest, then I do indeed get the same result:

<cfset createObject("component","cfide.adminapi.administrator").login("youradminpw")>
<cfset ws = createobject("component","CFIDE.adminapi.extensions")>
<cfdump var="#ws.getwebservices("test")#">

Now, you may wonder: "if I can't a listing unless I know the name, or can only get a list of 'all' of them if they are named, then how might I get the info for ones that have no name or whose name I don't know?"

Good question. And guess what I've found? A couple of important things.

First, I've found that you can also pass in the WSDL URL, even for a web service that's been renamed with an alias like "test", such that this works:

<cfset createObject("component","cfide.adminapi.administrator").login("youradminpw")>
<cfset ws = createobject("component","CFIDE.adminapi.extensions")>
<cfdump var="#ws.getwebservices("http://ws.invesbot.com/stockquotes.asmx?WSDL")#">

Again, that's not the web service name but the WSDL URL. And the resulting dump shows the name and that URL. So the API docs on this are a little misleading.

Be sure to refresh the "right" webservice: the one you'd really try calling

But perhaps a more important thing is that I found that you can have a web service entry for the SAME WSDL URL but with different names/aliases. Why is this important? Because you want to make sure you refresh whichever one you're using.

This goes back to my point above when I introduced the refreshWebService method: you need to give it the name as YOU call the web service, otherwise you'll be refreshing a different proxy stub and won't see the benefit you expect.

If you use the WSDL URL when you invoke the web service, then that will create a proxy stub with that "name", and therefore you want to use that as the "name" when you refresh it.

If you rename a web service in the Admin console, and then use that when you invoke the web service, then you want to use that as the "name" when you refresh it.

Refreshing Web Services Using the ServiceFactory

Since some folks reading this may not have moved to CF 7, let me show how you could do the same using CFMX 6/6.1 (or indeed 7, since it still works there). It's important to note, however, that using the ServiceFactory is not only not documented but it's also not supported. It has security problems (since there's no need to provide the admin password as you must in the Admin API). Also, it may eventually be obsoleted or otherwise restricted.

Still, since it's been documented by others in the past and is readily available on the web, I'll offer it here:

<cfobject action="CREATE" type="JAVA" class="coldfusion.server.ServiceFactory" name="ServiceFactory">
<cfset ServiceFactory.getXMLRPCService().refreshWebService("<em>webservicename</em>")>

Now, you'll notice that I've indicated that the value passed into the refreshWebService method is the webservicename. That's because it works just like the Admin API reloadWebService discussed at the top here. Be sure to specify the name as you would use it in the invocation of the web service (whether an alias or the full URL).

How to Confirm That Refreshing is Working

As you try these three approaches (Admin button, Admin API, and ServiceFactory), you will probably benefit greatly from being able to see for sure that the refresh/reload is updating the java proxy/stub class files. Where do you find them? They're stored in a "stubs" directory under your CFMX install directory, such as C:\CFusionMX\stubs or C:\CFusionMX7\stubs.

Then, under that, you will find directory names such as WS141836989, or a name that's the same as the alias/name you give to a web service in the Admin console. Inside those directories you will find other subdirectories, eventually finding some that hold the .class files representing the objects available in the web service. It's those .class files whose date/time stamp you want to see changing when you do a refresh/reload.

I'll note that there's no mapping or indication of that WSnnnn directory name, to know which one holds the web service you're interested in. I guess you just have to find the right one by looking for one whose class names map to the web service object you're calling. (If anyone knows a better connection, please do share it.)

Finally, I think it may be worth clarifying that when you do a refresh/reload of a web service using the approaches above, you need to have first made a call to that web service from CFML (or entered it manually in the admin console).

Hope all that's helpful.

Summary of Notes for Adobe Folks

Before I end, in case any Adobe folks are listening, here is a restatement (and expansion) of the couple of observations I made about wrong or undocumented functionality. This is for both the docs group and the engineers, since this is also about internal API documentation returned by the CFCs and their functionality:

  • getwebservices() only returns web services that have a name that was changed, whereas the API doc says it returns "all web services", so it either is working incorrectly or ought to be called getnamedwebservices instead
  • though not documented, getwebservices("wsdlurl") works also. The API docs say that it should only take a name (and I tested this against a web service where I had renamed it, so it was not getting it "by name")
  • if you do consider renaming the getwebservices() method to be called getnamedwebservices(), you might then also want to rename getwebservices(name) to getwebservice (singular), since it just gets one webservice
  • it would be nice to be able to refresh ALL webservices that use a given WSDL URL at once, perhaps by new method that accepts URL rather than name (and works for all occurrences of that URL in the cache, whether named with an alias or not)

Copyright ©2020 Charlie Arehart
Carehart Logo
BlogCFC was created by Raymond Camden. This blog is running version 5.005.
(Want to validate the html in this page?)

Managed Hosting Services provided by
Managed Dedicated Hosting