March 30th, 2004, 01:21 PM
cold fusion components as web services
I am currently developing a component to be used as a web service that I am going to be calling from a Java Applet.
I have been running into some perplexing and frustrating issue that I hope someone can help me with.
When I create components normally and invoke them from with cold fusion pages run on the server they work correctly.
I can create instances of other components inside of components, I can return instances of components from methods,
and pass instances to methods of components.
However, when I run a component as a web service I get errors because either AXIS or the cold fusion server cannot
find the other component types that I try to create from within my service. I seem to be able to create a component if it resides in the
same directory as the service component, but not if it resides somewhere else.
I am trying to return an array of component objects from my web service
I have a normal package structure defined for my components: ie. com.mycompany.blah.componentName, etc...
What is the correct placement of component files in the directory hierarchy?
Currently, all of our cold fusion files reside outside of the web directory and are accessed using web server virtual directories and
mappings in the cold fusion mx server itself. Is there any problem using components outside of the web directory like this?
As I mentioned, creating components works fine when instantiating them from a cold fusion page, just not as a web service.
If anyone has any ansight into this, any help would be greatly appreciated!
Thank you in advance,
March 30th, 2004, 02:45 PM
This is definitely getting into murky territory. It's one thing to return an array of strings, or a structure, or a query result set. But an array of objects? This could be difficult...I mean, how is the Java applet supposed to know what "kind" of objects CF is returning? Does Java treat it as a Java object, a collection, or what? You might consider playing with the <cfproperty> tag, which you can use to affect the wsdl that the Axis engine generates.
In any event, to address the apparant component path issues. First, start small and try to instantiate 1 CFC that returns just a string. Then try making it an object. Then try making it an object of a different type in the same package. Then an object in a different package. And finally, an array of objects. Make sure you are specifying the full path to the CFC in the argument and/or return type attribute.
March 31st, 2004, 10:50 AM
sorry, I should have clarified a little more...
I did start that way, and I got everything working fine
using the standard, simple data types. I also got a query
to return without any problems.
What I have created is the component service which is to
return another component or an array of components
from the method that is called.
I have created the component type to be returned, and have
place the cfproperty tags in it to tell the SOAP service what data to expect in the object.
I would prefer to return the array of components because then
the only thing I have to do on the client side is to create
a deserializer to create the proper Java objects.
My problem is that I cannot seem to use CreateObject of <CFOBJECT> to create any instances of the particular component
if it's code resides in a different directory than the service
March 31st, 2004, 11:31 AM
This is where I am confused. Are you saying that you are calling a component as a web service, and within THAT component, you are instantiating OTHER components, manipulating them, and returning them (or their data) to the web service invoker? So your web service is behaving as a facade?
Originally Posted by westwaveguy
If this is the case, can you instantiate the facade object directly with createObject()? Is the problem that you CAN create an instance using createObject(), but that you CAN'T call it via a web service?
March 31st, 2004, 12:08 PM
That is exactly what I am trying to do. The web service itself
is just the entry point to my business logic that is performed
by other components residing on the server.
In any cold fusion page ( or even any component that is not
being run as a Web Service ), I can use createObject to
create a component object that resides anywhere in the
package structure I created to hold my components.
I should probably give an example
I will call the component that I am invoking as a web service
I can invoke component1 as a web service and return any standard
type ( string, struct, cfquery, numbers, etc... ) and it works fine.
But, if inside of component1 I try to use createObject to make
a component2 ( to service my business logic, or whatever )
then createObject cannot find the path to component2 if
it does not reside in the same package directory as component1.
so if my package structure is com.mycompany.webservices.component1, and
com.mycompany.businesslogic.component2, then the web
service cannot find component2
but if my package structure is com.mycompany.webservices.component1
com.mycompany.webservices.component2 then it works fine.
I hope that is more clear,
March 31st, 2004, 12:34 PM
Ah, the problem may be that you need to specify the path/type to the CFC in your createObject() call:
createObject( 'component', 'wigetFactory' )
Will instantiate the CFC 'wigetFactory' that is in the same package (directory) as the caller. But if you are in '/com/dataModel' but wigetFactory is in '/com/factories', then you must specify the full path to the CFC you want to instantiate:
createObject( 'component', 'com.factories.wigetFactory' )
This path is either from the web root, or from any valid CF mapping. You can create a mapping in the CF administrator.
Is this the problem?
March 31st, 2004, 01:21 PM
I figured out the problem...
Thanks for the reply, I had been including the full path
to the component in my createObject calls.
But I have found the Answer!
Thanks for all of your help!
This is a known bug in Cold Fusion MX 6.1, posted on the
known issues page on the macromedia web site...
If you call local components within components that are declared as web services, the mappings set in the ColdFusion MX Administrator are ignored. To work around this problem, create a virtual directory for the folder with the mapping. For example, edit the jrun-web.xml file and create a mapping with the same data as the ColdFusion mapping, such as the following: