找不到ColdFusion Java方法异常

时间:2018-07-02 14:45:44

标签: java coldfusion

这个问题使我发疯。我正在尝试在ColdFusion中使用Java创建一个Document对象。当我这样做时:

nd = createObject("java","javax.xml.parsers.DocumentBuilder");

我可以转储nd并查看它正确加载了所有方法:

object of javax.xml.parsers.DocumentBuilder Class Name javax.xml.parsers.DocumentBuilder 

Method / Return Type

getDOMImplementation() / org.w3c.dom.DOMImplementation

getSchema() / javax.xml.validation.Schema 

isNamespaceAware() / boolean 

isValidating() / boolean 

isXIncludeAware() / boolean 

newDocument() / org.w3c.dom.Document 

parse(java.io.File) / org.w3c.dom.Document 

parse(java.lang.String) / org.w3c.dom.Document 

parse(org.xml.sax.InputSource) / org.w3c.dom.Document 

parse(java.io.InputStream, java.lang.String) / org.w3c.dom.Document 

parse(java.io.InputStream) / org.w3c.dom.Document 

reset() / void 

setEntityResolver(org.xml.sax.EntityResolver) / void 

setErrorHandler(org.xml.sax.ErrorHandler) / void 

我正在尝试调用newDocument()方法。我在cfscript和cfsets中都尝试了以下所有内容:

nd.newDocument();
nd.newDocument(JavaCast("null",""));
nd = createObject("java","javax.xml.parsers.DocumentBuilder").newDocument();
nd = createObject("java","javax.xml.parsers.DocumentBuilder").newDocument(JavaCast("null",""));

但是,无论我尝试哪种方法,都会出现此错误:

  

没有一种方法具有指定的方法名称和参数类型   或isNamespaceAware方法的参数类型过载   ColdFusion无法可靠地解密。 ColdFusion找到0个与>提供的参数匹配的方法。如果这是Java对象,并且您已验证方法>存在,请使用javacast函数来减少歧义。

我可以看到该方法已加载..该方法未重载..它不需要任何参数..而且,即使我明确告诉CF我要传递null,也找不到方法。

我尝试访问该类中的其他方法-并且也找不到这些方法。.我不确定为什么可以转储该类的内容-并且我可以看到所有方法。。但是,无论如何CF感到困惑,当我尝试调用它们时找不到它们。

任何想法都会很有帮助。

谢谢!

3 个答案:

答案 0 :(得分:6)

您必须为documentBuilder工厂创建一个对象。在工厂的帮助下,您可以获得实际的xml信息。在这里,我创建了对象,并使用documentbuilderfactory调用了parse方法。 同样,您必须注入newInstance(),然后才能访问newdocument()方法。 我的Xml内容:testParse.xml

conf/nifi.properties

* CF代码:

<?xml version="1.0"?>
<company>
<staff id="1001">
    <firstname>yong</firstname>
    <lastname>mook kim</lastname>
    <nickname>mkyong</nickname>
    <salary>100000</salary>
</staff>
<staff id="2001">
    <firstname>low</firstname>
    <lastname>yin fong</lastname>
    <nickname>fong fong</nickname>
    <salary>200000</salary>
</staff>
</company>

我希望它将对您有所帮助。谢谢。

答案 1 :(得分:0)

  

我尝试访问该类中的其他方法-但它无法   找到那些。.我不确定为什么我可以转储其中的内容   类-我可以看到所有方法。   感到困惑,当我尝试给他们打电话时找不到他们。

tldr;

要详细说明“为什么”,这是一条红色鲱鱼。错误的真正原因是DocumentBuilderabstract。您不能创建抽象类的实例。如existing answer中所述,您只能通过DocumentBuilderFactory创建一个新实例。

详细信息:

CreateObject实际上实际返回的是java类的代理。尽管它可能看起来像Java类的实例,但并非如此。它只是一个包装。注意手动创建的代理对象看起来与cfdump中的变量相同吗?

nd = createObject("java","javax.xml.parsers.DocumentBuilder");
proxy = createObject("java", "coldfusion.runtime.java.JavaProxy").init(nd.getClass());

writeDump(var=proxy, label="This is the JavaProxy");
writeDump(var=nd, label="This is the Variable 'nd'");

Dump of Proxy Object

关于CF为什么“找不到方法”的原因,这是令人误解的。错误的实际含义(在此特定情况下)是该方法确实存在,但是..您尚未被访问。

有两种相关的方法:

  • 实例方法:属于类的特定实例
  • 静态方法:属于整个类,可以被调用,而无需先创建该类的实例

由于JavaProxy的工作方式,在使用init(..)创建新实例之前,您只能访问静态方法。 转储中的方法,例如newInstance(),都是实例方法。由于您的代码没有调用init(...),因此CF搜索可用方法时,找不到newInstance(),这就是为什么您会收到“找不到方法错误”的原因。

第22集:

当然,如果您尝试实例化此特定类:

nd.init();

...它将失败。原因是DocumentBuilder是abstract class,所以您不能实例化它。但是,它至少会产生稍微更准确的错误消息:

  

找不到类的构造函数   接受类型('')的参数的javax.xml.parsers.DocumentBuilder。

长话短说,错误消息具有误导性。该方法确实存在,因为您没有该类的适当“实例”,所以无法访问该方法。正如existing answer所解释的那样,获取适当实例的唯一方法是通过DocumentBuilderFactory

答案 2 :(得分:0)

我在Java类上从ColdFusion调用方法时遇到了相同的错误。我试图使用如下所示的setPropertyName方法。

    <cfobject action="create" type="java" name="This.txnRequest" class="#AnetAPI#.TransactionRequestType" />
    <cfset authTxnType=CreateObject("java", "#AnetAPI#.TransactionTypeEnum") />
    <cfset This.txnRequest.setTransactionType(authTxnType.AUTH_CAPTURE_TRANSACTION) />

结果表明,ColdFusion希望您直接访问EJB中的属性。您还需要像这样显式调用EJB构造函数:

    <cfset This.txnRequest.init() />
    <cfset This.txnRequest.TransactionType=authTxnType.AUTH_CAPTURE_TRANSACTION />

CF如Adobe Docs中所述为您隐式调用set方法。您不能直接调用它。