使用Axis2重新启动现有Java对象的CF10 / CF11 Web服务

时间:2014-06-19 18:10:34

标签: coldfusion axis2

原帖:

这真的很奇怪。

我有一个自CFMX以来一直在工作的Web服务(即自CF6以来)。我们最近升级到CF10。 (不是我的选择,我游说CF11。)我们的用户需要旧的WSDL,因为他们基于旧格式的WSDL为他们的WS客户端生成了存根。所以我添加了wsversion =" 1"到cfcomponent标签。我们得到旧式WSDL,但webservices.log说"使用Axis 2 ..."。这是意料之外的,但不是我所指的真正奇怪的。继续阅读。

Web服务是无状态的。我听说现在可以通过CF网络服务实现会话控制,但我们并没有这样做。没有Application.cfc,没有cfapplication标签。所以每个cfinvoke都是它自己的,完全独立的执行,对吧?或者我想。 我在Web服务的之前的调用中定义的Web服务的后续调用中看到的东西。它好像是相同的内存是被重用。

例如,我使用变量(使用IsDefined)来检测条件。它发生在调用1.没问题,我修复它。但是变量仍然存在于调用2中!

我无条件地定义了一个UDF,因为它不会在调用的早期定义。在下一次调用时,它爆炸抱怨我试图定义UDF两次!同样的文件!该UDF名称仅在该文件中定义了一次!

我在一次调用中有条件地定义了一个数组和ArrayAppend跟踪消息,我看到同一个数组仍然存在,并且在后续调用中仍然包含相同的跟踪消息! (很难再次出现相同的时间戳。)

在重新启动CF Server之前,所有这些症状都会持续存在。不太好。不好根本

好像我们正在重新启动旧的,脏的CFM文件实例化'类,而不是做一个新的ClassName()来获取我们自己的后续调用独有的新副本。

启用可信任缓存是否。保存类文件为否。您认为单独使用这两个文件需要将.cfm重新编译为.java,然后将.java重新编译为.class,然后将.class重新编译为内存(重新开始)从头开始每次请求),不是吗?

这从未发生过,但它在CF10下始终如一。我的系统管理员是否遗漏了CF10发布文档中的内容?

更新(当天,美国东部时间下午5:40):

正如您在下面的评论和我的回答中所看到的,此问题仅被证明是Axis 2。 wsversion =" 1"我认为是在CFC中被编辑出来的,可能是其他一些善意的灵魂试图解决同样的问题。

由于这种CF10行为非常可怕,我获得了令人惊讶的快速部署2个实验性Web服务的许可。我现在有证据,一个简单的例子,A​​xis 2有问题(至少在我们的网站,我们的配置):

/experiments/cf10axis1.cfc:

<cfcomponent displayname="Axis 1 Service" wsversion="1">
<cffunction name="IsFooDefined" access="remote" returntype="string" output="No">
    <cfset Variables.Foo = IsDefined("Variables.Foo")>
    <cfreturn Variables.Foo>
</cffunction>
</cfcomponent>

/experiments/cf10axis2.cfc:

<cfcomponent displayname="Axis 2 Service" wsversion="2">
<cffunction name="IsBarDefined" access="remote" returntype="string" output="No">
    <cfset Variables.Bar = IsDefined("Variables.Bar")>
    <cfreturn Variables.Bar>
</cffunction>
</cfcomponent>

/experiments/call_both_cf10_webservices.cfm:

<cfinvoke webservice     = "http://((snip))/experiments/cf10axis1.cfc?wsdl"
          method         = "IsFooDefined"
          refreshWSDL    = "No"
          returnvariable = "Variables.Answer1">
</cfinvoke>
<cfinvoke webservice     = "http://((snip))/experiments/cf10axis2.cfc?wsdl"
          method         = "IsBarDefined"
          refreshWSDL    = "No"
          returnvariable = "Variables.Answer2">
</cfinvoke>
<cfoutput>
Variables.Answer1 = #Variables.Answer1#.<br/>
Variables.Answer2 = #Variables.Answer2#.<br/>
</cfoutput>

首次回复

Variables.Answer1 = NO.
Variables.Answer2 = NO.

所有后续通话都会返回

Variables.Answer1 = NO.
Variables.Answer2 = YES.

无法获得更明确的证据。

该死的我喜欢StackOverflow如何干净利落地呈现CFML。特别甜。

确认:

这最初发生在Sun Sparc Solaris的CF10中。我刚刚在MacBook Pro上在CF11中运行了相同的简约测试(上图)并得到了完全相同的结果。我已经从这篇文章的标题中删了问号,我已经说过CF10 / CF11了。它不再是问题。

我不认为这是一个CF错误。它的Axis2就是这样做的。

这对人们如何编码有严重影响,但我无法在网上找到任何提及。仅仅因为你没有在调用中做某事,并不意味着它在记忆中不是这样。中止标志保持不变。你不能使用cfparams;你必须使用cfsets。每个UDF都必须从属于cfif而不是IsDefined()。心灵难以置信。

我是第一个发现这个的人吗? CF11出局了。在CF中使用Axis2是没人吗?

如果我不是一个如此自然快乐的人,我现在就会感到非常沮丧。 :-)

2 个答案:

答案 0 :(得分:1)

这不是Axis 2中的问题。

这是对Axis 2 Web服务支持设计方式的行为变化。

在Axis 1中,对于每个Web服务请求,都会创建一个新的CFC实例,并且该请求由此新实例处理。这就是为什么变量总是为每个请求重新初始化。

在Axis 2中,仅在您第一次访问服务时创建CFC实例(首次访问WSDL或首次调用Web服务)。对于每个后续请求,使用相同的实例。所以你看到那里的缓存。仅在修改服务CFC时才会创建新的CFC实例。

通常,如果要部署基于axis2的aar(使用Java),在tomcat中,您将看到相同的行为。即,如果您的类具有状态并且在Web服务功能中修改了该状态,您将在下一个请求中获得修改后的值。

这是我们为提高性能而做出的设计决策(不是每次都初始化实例并使用Axis 2框架注册它,而是重新使用实例)。您是否要求为每个Web服务请求使用不同的CFC实例?

答案 1 :(得分:0)

dom_watson(Dominic Watson)在上面发布了一个可行的解决方案。我希望我可以给他正确答案,但我无法弄清楚如何做到这一点。 (是的,我是StackOverflow的新手。是的,我道歉。)

起初我并不抱有希望。毕竟,Axis2 Web服务包含的文件也受到缓存的影响,即使它们被编译为单独的Java类文件。似乎完全可怕的是CreateObject()会获取对象的内存中副本。

那并没有发生。

/experiments/cf10axis2proxy.cfc(Axis2网络服务):

<cfcomponent displayname="Axis2Proxy" wsversion="2">
<cffunction name="IsImpDefined" access="remote" returntype="string" output="No">
    <cfset Variables.ImplObject = CreateObject("component", "experiments.cf10axis2impl")>
    <cfreturn Variables.ImplObject.IsImpDefined()>
</cffunction>
</cfcomponent>

/experiments/cf10axis2impl.cfc(注意,甚至不是网络服务,访问是&#34;公共&#34;):

<cfcomponent displayname="Axis2Implementation">
<cffunction name="IsImpDefined" access="public" returntype="string" output="No">
    <cfset Variables.Imp = IsDefined("Variables.Imp")>
    <cfreturn Variables.Imp>
</cffunction>
</cfcomponent>

添加到/experiments/call_both_cf10_webservices.cfm(见上文):

<cfinvoke webservice     = "http://((snip))/experiments/cf10axis2proxy.cfc?wsdl"
          method         = "IsImpDefined"
          refreshWSDL    = "Yes"
          returnvariable = "Variables.Answer3">
</cfinvoke>

当然,还将variables.Answer3添加到cfoutput显示中。

首次执行产生了

Variables.Answer1 = NO.
Variables.Answer2 = NO.
Variables.Answer3 = NO.

并且所有后续执行都产生了

Variables.Answer1 = NO.
Variables.Answer2 = YES.
Variables.Answer3 = NO.

因此经过测试和确认(尽管有文件名,仍在CF11下)。 dom_watson的建议使得Axis2 Web服务的cfinvoke行为符合https://wikidocs.adobe.com/wiki/display/coldfusionen/cfinvoke 所说的 cfinvoke行为:

  • 实时实例化组件或Web服务并在其上调用方法。

(重点补充)。

谢谢你,多米尼克。