Reputation: 4622
I've got a CFC that I'm going to access with ?wsdl as a SOAP webservice.
If I call the CFC directly in a browser, my results render fine:
http://server/webservice/calc.cfc?method=doStuff&foo=bar
If I try to access it as a web service:
ws = CreateObject("webservice", 'http://server/webservice/calc.cfc?wsdl');
result = ws.doStuff('bar');
I get an error:
Cannot perform web service invocation doStuff.
The fault returned when invoking the web service operation is:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: coldfusion.xml.rpc.CFCInvocationException:
[coldfusion.xml.rpc.CFCInvocationException : [java.lang.ClassNotFoundException :
com.calculations.calc][java.lang.NullPointerException : null]]
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:coldfusion.xml.rpc.CFCInvocationException: [coldfusion.xml.rpc.CFCInvocationException : [java.lang.ClassNotFoundException :
com.calculations.calc][java.lang.NullPointerException : null]]
at coldfusion.xml.rpc.CFComponentSkeleton.__createCFCInvocationException(CFComponentSkeleton.java:733)
at coldfusion.xml.rpc.CFComponentSkeleton.__convertOut(CFComponentSkeleton.java:359)
at webservice.calc.doStuff(/var/www/vhosts/server/httpdocs/webservice/calc.cfc)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.r... ''
The problem is because the doStuff function is declaring an instance of a CFC inside it:
remote struct function doStuff(foo) {
var objReturn = {};
objReturn.msg = 'A message';
// do a calculation
var objCalc = new com.calculations.calc(foo);
objReturn.calc = objCalc;
return objReturn;
}
So my CFC that I'm using as a webservice has got another CFC being declared inside a function. Browsing directly to my webservice CFC works fine, but trying to call it using the CreateObject/webservice route fails, as it can't create an instance of the com.calculations.calc component.
UPDATE:
If I refresh the page a few times, sometimes the error changes to:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: coldfusion.xml.rpc.CFCInvocationException:
[coldfusion.xml.rpc.CFCInvocationException : [java.lang.ClassNotFoundException :
com.calculations.calc][coldfusion.xml.rpc.CFCInvocationException :
returnType must be defined for remote CFC functions.]]
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:coldfusion.xml.rpc.CFCInvocationException:
[coldfusion.xml.rpc.CFCInvocationException : [java.lang.ClassNotFoundException :
com.calculations.calc][coldfusion.xml.rpc.CFCInvocationException :
returnType must be defined for remote CFC functions.]]
at coldfusion.xml.rpc.CFComponentSkeleton.__createCFCInvocationException(CFComponentSkeleton.java:733)
at coldfusion.xml.rpc.CFComponentSkeleton.__convertOut(CFComponentSkeleton.java:359)
at webservices.TaxCalc.feed.getTaxCalc(/var/www/vhosts/server/httpdocs/webservice/calc.cfc)
at sun.reflect.Nat... ''
This is asking for a return type, but the init func of com.calculations.calc has return this;
Upvotes: 2
Views: 4241
Reputation: 4622
Ok this doesn't really answer the question as to why the error was being thrown, but I've found a workaround. Instead of using this code:
objReturn.calc = objCalc;
I've used this instead:
objReturn.calc.arrOne = objCalc.getArrOne();
objReturn.calc.arrTwo = objCalc.getArrTwo();
And it's working fine. I guess the problem is something to do with the fact that the component can't be translated into data for the WSDL. I was thinking of the CFC as a struct, which it isn't as it has loads of methods attached to it.
So I shouldn't be trying to assign the CFC, I should be using the accessors to access the data inside the CFC.
Answer also on Abobe forums: http://forums.adobe.com/message/4326548
Upvotes: 1
Reputation: 1964
Your function needs to be declared remote to access it as a webservice. The function itself is fine, which is why you can manually pull it up in the web browser.
remote function doStuff(foo){ }
Upvotes: 2