2

I have a .cfm file with the following code:

<cfset myObj=CreateObject( "java", "Test" )/>
<cfset a = myObj.init() >
<cfoutput>
    #a.hello()#
</cfoutput>
<cfset b = a.testJava() >

<cfoutput>
    #testJava()#
</cfoutput>

This references a Java class file:

public class Test
{
    private int x = 0;
    public Test(int x) {
            this.x = x;
    }
    public String testJava() {
            return "Hello Java!!";
    }
    public int hello() {
            return 5;
    }
}

I get the error:

The hello method was not found.

Either there are no methods with the specified method name and argument types or the hello 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.

I have tried many different ways and have followed the documentation exactly, here. The .class file is in the correct location because I FNF error is thrown if the file is removed.

I have also attempted using a cfobject tag in a similar manner with no luck. None of the methods are found. Any ideas?

Coldfusion 11, Hotfix 7

Leigh
  • 28,765
  • 10
  • 55
  • 103
theblindprophet
  • 7,767
  • 5
  • 37
  • 55

1 Answers1

1

I suspect you are running into a naming conflict. Since the java source does not include a package name, the class becomes part of the default package space. That can cause problems if a different class (having that same name), was already loaded. The JVM would have no way of knowing which "Test" class you wanted.

Choosing a different (more unique) class name should resolve the issue. At least for testing. However, in the long term, it is better to group classes into packages to avoid similar naming conflicts in the future.

Typically custom classes are bundled into .jar files for easier deployment. See Java: Export to a .jar file in Eclipse. To load jar files in CF you can either:

  • Load them dynamically via the new CF10+ application setting this.javaSettings -or-
  • Place the physical .jar file somewhere in the CF class path, such as {cf_web_root}/WEB-INF/lib. Then restart the CF Server so the new jar is detected.

Java

package com.mycompany.widgets;
public class MyTestClass
{
    private int x;
    public MyTestClass(int x) {
            this.x = x;
    }
    public String testJava() {
            return "Hello Java!!";
    }
    public int hello() {
            return 5;
    }
}

ColdFusion:

 <cfset myObj = CreateObject( "java", "com.mycompany.widgets.MyTestClass" ).init( 5 ) />
 <cfdump var="#myObj#">

 <cfset resourcePath = "/"& replace(myObj.getClass().getName(), "." , "/")& ".class">
 <cfset resourceURL = getClass().getClassLoader().getResource( resourcePath )>

<cfoutput>
    <br>Resource path:  #resourcePath#
    <br>Resource URL <cfif !isNull(resourceURL)>#resourceURL.toString()#</cfif>
    <br>myObj.hello() = #myObj.hello()#
    <br>myObj.testJava() = #myObj.testJava()#
</cfoutput>

NB: While not the norm, you can technically use packages with individual class files. However, you must copy the entire package structure into the WEB-INF\classes folder. For example, using the class above, the compiled class file should be copied to:

 c:/{cfWebRoot}/web-inf/classes/com/mycompany/widgets/MyTestClass.class
Community
  • 1
  • 1
Leigh
  • 28,765
  • 10
  • 55
  • 103