0

Scenario: I am doing a spike to see the feasibility of Java application communicating to another ColdFusion application which resides on the same JVM. The intention is to create micro services using springboot on top of existing ColdFusion application.

Problem: To do my investigation, I am using CFProxy library provided by ColdFusion. I have added the cfusion jar to the java classpath and my Java application is compiling correctly. While running the application I am getting ClassNotFoundException

Code:

import coldfusion.cfc.CFCProxy;
public class JavaIntegration {

public String sayHelloThroughCF(String name){
    String message = "";
    ClassLoader classLoader = getClass().getClassLoader();
    System.out.println("ClassLoader: " + classLoader);


    try{
        CFCProxy employeeCFC = new CFCProxy("C:\\Sites\\lb-bo-dev\\JavaIntegration\\employee.cfc", true);
        Object[] args = {name};
        message = (String) employeeCFC.invoke("sayCFHello", args);
    }
    catch(Throwable e) {
        e.printStackTrace();
    }
    return message;
    }
}

Error Message:

java.lang.NoClassDefFoundError: javax/servlet/Servlet
    at JavaIntegration.sayHelloThroughCF(JavaIntegration.java:11)
    at HelloWorld.main(HelloWorld.java:4)
Caused by: java.lang.ClassNotFoundException: javax.servlet.Servlet
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

Note: I am able to successfully complete the transaction if I am triggering code from ColdFusion. In this scenario, I have added the java jar to coldfusion classpath. ie ColdFusion--> Java --> ColdFusion is working without any issue. Please find below the ColdFusion code

index.cfm:

<cfscript>
    a = createObject("java", "cfintegration.JavaObject");
</cfscript>
<cfdump var="#a.sayHelloThroughCF('my name in cf')#"><br/>

Employee.cfc

<cfcomponent output="false" displayname="Employee">
    <cffunction name="sayCFHello" access="public" output="false" returntype="String">
        <cfargument name="name" required="true" />
        <cfreturn "ColdFusion says hello to " & arguments.name />
    </cffunction>
</cfcomponent>
SOS
  • 6,430
  • 2
  • 11
  • 29
arp
  • 1,423
  • 2
  • 10
  • 11
  • I could be wrong, but ... I don't think you can use the CFCProxy outside of CF. If you think about it a CFC would need a CF server to function (ex. parse and execute CFML code). The docs say "To call [a] CFC, ColdFusion class loader must be the current class loader". I don't see how that could happen without running the java app in CF or at least on the same JVM. – SOS Jul 31 '18 at 16:47
  • @ageax Agree with you. I am puzzled and stuck right now. I could be stupid but do you think we can add a custom class loader for Java which loads the CF classes? But I assume CF classes will be available only while we run the application? – arp Jul 31 '18 at 18:13
  • That's the part I don't quite understand either. You can certainly create a custom classloader - or switch the current class loader - but ... even if you could load all the necessary jars, I still don't see how it could work without a CF engine running. Btw, the part about switching the class loader I read in old threads on the JavaLoader group. I don't think it's very active anymore, so you may want to ask on the cfml slack channel instead https://cfml-slack.herokuapp.com/ – SOS Jul 31 '18 at 18:53
  • 1
    **Update:** 1. Although I don't think it'll resolve the broader issue (invoking CFC's from a java app), the ClassNotFound error is probably because you didn't add the javax.servlet jar to your class path. Look for a jar with a name like `servlet-api-###.jar` in the CF root folders. 2. Instead of trying to invoke native CFC's, have you considered using web services ? That would work and would be easier... – SOS Jul 31 '18 at 19:04
  • I will try add javax.servlet to classpath. We did consider Webservice and it's the final fallback if nothing works. We are trying to avoid http calls as part of the request as a single request may need to make multiple calls to CF service. – arp Jul 31 '18 at 19:48
  • I have a bad feeling WS may be the only option, but ... ask on the slack channel. Someone there should be able to confirm it at least, one way or the other... – SOS Jul 31 '18 at 19:52
  • I have added the servlet jar files to classpath and now getting runtime error. coldfusion.server.ServiceFactory$ServiceNotAvailableException: The Runtime service is not available. at coldfusion.server.ServiceFactory.getRuntimeService(ServiceFactory.java:117) at coldfusion.cfc.CFCProxy.(CFCProxy.java:119) at coldfusion.cfc.CFCProxy.(CFCProxy.java:73) at JavaIntegration.sayHelloThroughCF(JavaIntegration.java:11) at HelloWorld.main(HelloWorld.java:4) – arp Aug 01 '18 at 08:53
  • Well that's good and bad. Good because it confirms javax.servlet.* is required. Bad because it implies the code may not work outside of CF, like we suspected. Before investing any more time in adding dependencies, I'd ask for a confirmation on the slack channel, because I have a strong suspicion the answer is "No. You can't use CFC's outside of CF". – SOS Aug 01 '18 at 14:00
  • I have already asked in the slack channel. – arp Aug 01 '18 at 15:45
  • Oh, okay. Please let us know if you get an answer one way or the other. As I've never been 100% sure about this one.. – SOS Aug 01 '18 at 15:51
  • Did you ever get an answer about this? – SOS Sep 11 '18 at 11:31

0 Answers0