Problem with JavaLoader with Certain Web Services

125 views
Skip to first unread message

Jamie Jackson

unread,
Mar 13, 2013, 5:32:02 PM3/13/13
to javaloa...@googlegroups.com
Hi Folks,

I've got another issue to work through. There's a third-party web service provider, and they require that you hit their WSDL from CF, then manually put the generated client stubs (java classes) on the CF classpath, so that you can instantiate some objects to help interact with the web services. Seems like a weird approach; but admittedly, I haven't consumed enough web services to be able to criticize.

Anyway this throws an error when I try to use the JavaLoader-loaded object as an argument in the ws-loaded object (line 8 in the Gist, below). I think that even though the class name matches, they're from different contexts, so it thinks the argument is of the wrong type.

I guess this might be another ThreadContext issue(?), but I don't know how to resolve it. (I haven't been able to get my head around the ThreadContext dilemma nor the solution in the wiki, yet.)


struct
DetailEither there are no methods with the specified method name and argument types or the setStatus method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.
MessageThe setStatus method was not found.
MethodNamesetStatus
StackTracecoldfusion.runtime.java.MethodSelectionException: The setStatus method was not found. at coldfusion.runtime.java.ObjectHandler.findMethodUsingCFMLRules(ObjectHandler.java:383) at coldfusion.runtime.StructBean.invoke(StructBean.java:524) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2393) at cfthing2ecfm717212895.runPage(/var/www/apps/onecpd/wwwroot/deleteme_jj/thing.cfm:46) at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231) at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416) at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65) at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:360) at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48) at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at coldfusion.filter.PathFilter.invoke(PathFilter.java:94) at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:27) at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70) at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62) at coldfusion.CfmServlet.service(CfmServlet.java:200) at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) at jrun.servlet.FilterChain.doFilter(FilterChain.java:86) at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46) at jrun.servlet.FilterChain.doFilter(FilterChain.java:94) at jrun.servlet.FilterChain.service(FilterChain.java:101) at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42) at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286) at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543) at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203) at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428) at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
TagContext
array
1
struct
COLUMN0
IDCF_STRUCTBEAN
LINE46
RAW_TRACEat cfthing2ecfm717212895.runPage(/var/www/apps/onecpd/wwwroot/deleteme_jj/thing.cfm:46)
TEMPLATE/var/www/apps/onecpd/wwwroot/deleteme_jj/thing.cfm
TYPECFML
TypeObject
number0

Jamie Jackson

unread,
Mar 13, 2013, 6:12:34 PM3/13/13
to javaloa...@googlegroups.com
And here's my ham-fisted attempt at using switchThreadContextClassLoader(), which fails miserably (cfc, calling cfm, and stack trace included): https://gist.github.com/jamiejackson/5156840

--
You received this message because you are subscribed to the Google Groups "javaloader-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javaloader-de...@googlegroups.com.
To post to this group, send email to javaloa...@googlegroups.com.
Visit this group at http://groups.google.com/group/javaloader-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Mark Mandel

unread,
Mar 13, 2013, 6:48:30 PM3/13/13
to javaloa...@googlegroups.com
Sounds like it's exactly what the error message says:

Either there are no methods with the specified method name and argument types or the setStatus method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.

Doesn't look like anything to do with the ThreadContextClassLoader

Mark

--
You received this message because you are subscribed to the Google Groups "javaloader-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javaloader-de...@googlegroups.com.
To post to this group, send email to javaloa...@googlegroups.com.
Visit this group at http://groups.google.com/group/javaloader-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jamie Jackson

unread,
Mar 13, 2013, 7:07:23 PM3/13/13
to javaloa...@googlegroups.com
But I'm calling the method with (what seems to be) the right signature:

user = ws.GenerateUserObject();
userStatus = javaLoader.create("com.geolearning.geonext.webservices.Status").Active;

writeDump(var=user, abort=false, expand=false);

object of com.geolearning.geonext.webservices.User
Class Namecom.geolearning.geonext.webservices.User
Methods
Parent Class
object com.geolearning.geonext.webservices.Persistent
Class Name com.geolearning.geonext.webservices.Persistent
Methods
MethodReturn Type
<snip><snip>
setStatus(com.geolearning.geonext.webservices.Status)void

writeDump(var=userStatus, abort=false, expand=false);
object of com.geolearning.geonext.webservices.Status
Class Name com.geolearning.geonext.webservices.Status
Methods
Fields


Do you see what I mean? On the surface, the signatures match, but if I do user.setStatus(userStatus), I get the aforementioned error.

Thanks,
Jamie

Mark Mandel

unread,
Mar 13, 2013, 7:20:22 PM3/13/13
to javaloa...@googlegroups.com
Could be a CF bug... I've seen it have issues resolving parent methods.

Is there a setStatus() method on the User? (not the parent) that it could be getting confused with?

Mark

Mark Mandel

unread,
Mar 13, 2013, 7:20:57 PM3/13/13
to javaloa...@googlegroups.com
Is the method a public method?

Do you have some javadoc for this object? Or the original source?

Mark

Jamie Jackson

unread,
Mar 13, 2013, 7:36:55 PM3/13/13
to javaloa...@googlegroups.com
On Wed, Mar 13, 2013 at 7:20 PM, Mark Mandel <mark....@gmail.com> wrote:
Is the method a public method?

Yes. I don't think it would show up in the cfdump without it. Also, the same code works if it is added to the cf classpath (in jvm.config) and used with creatObject("java", ..., instead of JavaLoader.
 
Do you have some javadoc for this object? Or the original source?

Mark Mandel

unread,
Mar 13, 2013, 7:43:30 PM3/13/13
to javaloa...@googlegroups.com

On Thu, Mar 14, 2013 at 10:36 AM, Jamie Jackson <jamie...@gmail.com> wrote:
Yes. I don't think it would show up in the cfdump without it. Also, the same code works if it is added to the cf classpath (in jvm.config) and used with creatObject("java", ..., instead of JavaLoader.

You have a gist of that? There may be some differences in the code.

Mark

Jamie Jackson

unread,
Mar 13, 2013, 7:44:06 PM3/13/13
to javaloa...@googlegroups.com
On Wed, Mar 13, 2013 at 7:20 PM, Mark Mandel <mark....@gmail.com> wrote:
Could be a CF bug... I've seen it have issues resolving parent methods.

I dunno, this whole thing works with these web service stubs added to the cf classpath (in jvm.config) and used with creatObject("java", ..., instead of JavaLoader. Doesn't that disprove this theory?
 
Is there a setStatus() method on the User? (not the parent) that it could be getting confused with?

I'm not sure if I have a way of knowing, but none shows up in the method dump of User, itself.


object of com.geolearning.geonext.webservices.User
Class Namecom.geolearning.geonext.webservices.User
Methods
Method Return Type
<snip> <snip>
setState(java.lang.String) void
setStreetAddress(java.lang.String) void
<snip> <snip>
Parent Class
object com.geolearning.geonext.webservices.Persistent
Class Name com.geolearning.geonext.webservices.Persistent
Methods
MethodReturn Type
<snip><snip>
getStatus()com.geolearning.geonext.webservices.Status
<snip><snip>

Jamie Jackson

unread,
Mar 13, 2013, 7:51:55 PM3/13/13
to javaloa...@googlegroups.com
Here are the relevant pieces when the stubs are added to the cf classpath via jvm.config:

--

Mark Mandel

unread,
Mar 13, 2013, 8:07:04 PM3/13/13
to javaloa...@googlegroups.com
Uh. I'm willing to bet you're trying to use Javaloader and have classpath set at the server level at the same time.

(a) that's a bad idea (b) not sure if this will work with Javaloader without it.

See:

ws = createObject("webservice", local.lms.wsurl)
user = ws.GenerateUserObject();

That's generated from ColdFusion.


UserStatus = javaLoader.create("com.geolearning.geonext.webservices.Status");

That's generated from JavaLoader

user.setStatus(UserStatus.Active);

That's mixing classpaths.

you * may* be able to fix this by switching up the threadcontext classloader.

Be tempted to see if you ran the block of code in a switched out TCCL, if it would work. It *may*

Mark


Jamie Jackson

unread,
Mar 13, 2013, 8:15:09 PM3/13/13
to javaloa...@googlegroups.com
On Wed, Mar 13, 2013 at 8:07 PM, Mark Mandel <mark....@gmail.com> wrote:
Uh. I'm willing to bet you're trying to use Javaloader and have classpath set at the server level at the same time.

No, this CF instance is clean. I'm trying *only* javaloader in this instance.
 
(a) that's a bad idea (b) not sure if this will work with Javaloader without it.

I didn't understand (b), exactly.
 
See:
ws = createObject("webservice", local.lms.wsurl)
user = ws.GenerateUserObject();

That's generated from ColdFusion.

UserStatus = javaLoader.create("com.geolearning.geonext.webservices.Status");

That's generated from JavaLoader

user.setStatus(UserStatus.Active);

That's mixing classpaths.

Right, that's what I was trying to get at in my OP, but I don't know the lingo.

you * may* be able to fix this by switching up the threadcontext classloader.

Be tempted to see if you ran the block of code in a switched out TCCL, if it would work. It *may*

That's what I'd tried here (https://gist.github.com/jamiejackson/5156840), but I don't have any experience with TCCL, and I was having trouble before I even got to the block in question.

I'm getting the feeling that javaloader and createObject("webservice", ...) just won't mix. That might just be me being a pessimist, though.

Jamie Jackson

unread,
Mar 14, 2013, 9:56:32 AM3/14/13
to javaloa...@googlegroups.com
So, assuming that ThreadContextClassLoader is the only way to get a web service Java object in the same context as JavaLoader (if it's even possible at all), I'll need help with TCCL. 

https://gist.github.com/jamiejackson/5156840

Do you spot what I'm doing wrong? Even with the foo method just stubbed out (none of my code inside), it fails, so I'm having problem using TCCL, itself.

Chris Blackwell

unread,
Mar 14, 2013, 11:05:00 AM3/14/13
to javaloa...@googlegroups.com

iirc createobject("webservice") uses apache axis to compile the weber vice into a set of classes. If you can't mix CF generated ws with java loader,  you could try using axis to compile the ws externally and then loading everything through java loader?

Jamie Jackson

unread,
Mar 25, 2013, 7:00:32 PM3/25/13
to javaloa...@googlegroups.com
For posterity: I went to Stack Overflow, and Leigh helped me find a solution: http://stackoverflow.com/questions/15506237/getting-coldfusion-called-web-service-to-work-with-javaloader-loaded-objects

--

Mark Mandel

unread,
Mar 25, 2013, 7:06:59 PM3/25/13
to javaloa...@googlegroups.com
Oh that makes a lot of sense.

Wonder what would have happened if you just turned on having the CF classpath be the parent.

But that works well.

Although, make sure not to recreate that JL instance over and over, you'll end up with a permgen memory leak.

Mark

Jamie Jackson

unread,
Mar 25, 2013, 7:14:26 PM3/25/13
to javaloa...@googlegroups.com
On Mon, Mar 25, 2013 at 7:06 PM, Mark Mandel <mark....@gmail.com> wrote:
Oh that makes a lot of sense.

Wonder what would have happened if you just turned on having the CF classpath be the parent.

That didn't work. Those client classed don't exist in the general CF classpath, they seem to be "private" to the web service, itself.

But that works well.

Although, make sure not to recreate that JL instance over and over, you'll end up with a permgen memory leak.

Thanks for that tip. That's something I'll need to work in.

On a related note, though, since I need to create JavaLoader in the context of the web service: Are web service objects candidates for keeping in a persistent scope? As far as I know, they're Singletons, but I don't know if they have some sort of limited lifespan that would prevent me from only creating them once (say in the app scope).

(I'm new to consuming web services from CF, so I haven't worked out all of this stuff out yet.)

Mark Mandel

unread,
Mar 25, 2013, 7:19:10 PM3/25/13
to javaloa...@googlegroups.com
On Tue, Mar 26, 2013 at 10:14 AM, Jamie Jackson <jamie...@gmail.com> wrote:


On Mon, Mar 25, 2013 at 7:06 PM, Mark Mandel <mark....@gmail.com> wrote:
Oh that makes a lot of sense.

Wonder what would have happened if you just turned on having the CF classpath be the parent.

That didn't work. Those client classed don't exist in the general CF classpath, they seem to be "private" to the web service, itself.

Ah fair enough. Sounds like you hit the nail on the head - CF is using it's own dynamic classloaders for external web services (makes sense really).
 

But that works well.

Although, make sure not to recreate that JL instance over and over, you'll end up with a permgen memory leak.

Thanks for that tip. That's something I'll need to work in.

On a related note, though, since I need to create JavaLoader in the context of the web service: Are web service objects candidates for keeping in a persistent scope? As far as I know, they're Singletons, but I don't know if they have some sort of limited lifespan that would prevent me from only creating them once (say in the app scope).

(I'm new to consuming web services from CF, so I haven't worked out all of this stuff out yet.)

TBH, I'm not 100% sure. But I can't see any reason why you wouldn't. (Or even wrap it up in a Business Delegate and persist it in that, and keep the web service call abstracted).

Mark
 
Reply all
Reply to author
Forward
0 new messages