The scenario, in which I lose access, is as follows:
a.cfc injected with b.cfc
I have another CFC, called c.cfc, which has an implicit getter & setter for setting & getting a.cfc. By the way, for implicit [accessors=true, cfproperty etc ] getters & setters, I set in the constructor.
I then call a method in c.cfc from a CF page template. Something, like c.HelloWorld()...
c.cfc then makes a method call like getA().Foo() from within HelloWorld()...
Inside the method a.Foo(), there is another call to getB().Bar()
Only in Railo/Lucee, do I get an error [ACF is fine]:
Component [conversionService] has no accessible Member with name [DATABASE2SERVICE]
Then a bit more detail:
string Component [conversionService] has no accessible Member with name [DATABASE2SERVICE] at lucee.runtime.ComponentScopeShadow.get(ComponentScopeShadow.java:127):127 at com.services.conversionservice_cfc$cf.udfCall1(C:\domains\establishmindfulness.com\wwwroot\com\services\conversionService.cfc:42):42 at ...
So, a recap:
CF page -> c.HelloWorld() [implicit A setter & getter] -> getA.Foo() [explicit B setter & getter] -> getB.Bar()
Now, the really bizarre thing, is that if I call a.Foo() from a CF page template, everything works fine. It is only when I go via an intermediary. [c.HelloWorld()]
One other piece of information:
The method call getA().Foo() from within c.HelloWorld() is made from inside a cfsavecontent tag.
I wonder whether 'cfsavecontent' is causing a problem, because I have other scenarios, just like this one, that work in Lucee/Railo [calling an injected CFC via an intermediary, but not from within cfsavecontent]
<cfcomponent displayname="application">
<cffunction name="OnRequestStart">
<cfargument name="TargetPage" type="string">
<cfset var local = {}>
<cfset request.servicelist = "dateService,translationService,test1Service,test2Service,test3Service">
<cfset request.daolist = "categorysectorDAO,venueDAO">
<cfset request.circulardependencies = StructNew()>
<cfset request.circulardependencies["test1Service"] = ["setTest2Service"]>
<cfset request.circulardependencies["test2Service"] = ["setTest1Service"]>
<cfset request.requestkey = structNew()>
<cfset request.domain_dsn = "dsn">
<cfset request.requestkey.domain_dsn = request.domain_dsn>
<cfif not StructKeyExists(APPLICATION,"servicefactory") or request.appreload>
<cflock name="servicefactory" type="exclusive" timeout="1000">
<cfset application.servicefactory = createobject("component","com.serviceFactory").init(request.servicelist,request.daolist,request.circulardependencies,request.requestkey)>
</cflock>
</cfif>
<cflock name="servicefactorylck" type="readonly" timeout="1000">
<cfset request.lckservicefactory = application.servicefactory>
</cflock>
<cfreturn true />
</cffunction>
</cfcomponent>
<cfcomponent displayname="serviceFactory">
<cffunction name="init">
<cfargument name="servicelist" type="string">
<cfargument name="daolist" type="string">
<cfargument name="circulardependencies" type="struct">
<cfargument name="requestkey" type="struct">
<cfset var local = StructNew()>
<cfloop list="#arguments.servicelist#" index="local.service">
<cfset this[local.service] = CreateObject("component","services.#local.service#").init(this,arguments.requestkey) />
</cfloop>
<cfloop list="#arguments.daolist#" index="local.dao">
<cfset this[local.dao] = CreateObject("component","services.dataAccess.#local.dao#").init(this,arguments.requestkey) />
</cfloop>
<cfif NOT StructIsEmpty(arguments.circulardependencies)>
<cfloop collection="#arguments.circulardependencies#" item="local.key">
<cfif IsArray(arguments.circulardependencies[local.key]) AND ArrayLen(arguments.circulardependencies[local.key])>
<cfloop from="1" to="#ArrayLen(arguments.circulardependencies[local.key])#" index="local.index">
<cfset local.object = local.key>
<cfset local.setter = arguments.circulardependencies[local.key][local.index]>
<cfif REFind("^set[A-Z]{1}[A-Za-z0-9_]+(Service|DAO)$",local.setter)>
<cfset local.argumentvalue = Mid(local.setter,4,Len(local.setter))>
<cfset local.temp = LCase(Left(local.argumentvalue,1)) & Right(local.argumentvalue,Len(local.argumentvalue)-1)>
<cfset local.argumentvalue = local.temp>
<cfinvoke component="#this[local.object]#" method="#local.setter#" service="#this[local.argumentvalue]#" />
</cfif>
</cfloop>
</cfif>
</cfloop>
</cfif>
<cfreturn this />
</cffunction>
</cfcomponent>
<cfcomponent displayname="test1Service" accessors="true">
<cfproperty name="dateService" type="struct">
<cfproperty name="translationService" type="struct">
<cffunction name="init">
<cfargument name="service" type="struct">
<cfargument name="requestkey" type="struct">
<cfset variables.service = arguments.service>
<cfset variables.requestkey = arguments.requestkey>
<cfset setDateService(CreateObject("component","dateService").init(this,variables.requestkey))>
<cfset setTranslationService(CreateObject("component","translationService").init(this,variables.requestkey))>
<cfreturn this />
</cffunction>
<cffunction name="getTest2Service">
<cfreturn variables.test2Service />
</cffunction>
<cffunction name="setTest2Service">
<cfargument name="service" type="component">
<cfset variables.test2Service = arguments.service>
</cffunction>
<cffunction name="Foo">
<cfset var result = "foo">
<cfreturn result />
</cffunction>
<cffunction name="Bar">
<cfset var result = getTest2Service().Bar()>
<cfreturn result />
</cffunction>
</cfcomponent>
<cfcomponent displayname="test2Service" accessors="true">
<cfproperty name="dateService" type="struct">
<cfproperty name="translationService" type="struct">
<cffunction name="init">
<cfargument name="service" type="struct">
<cfargument name="requestkey" type="struct">
<cfset variables.service = arguments.service>
<cfset variables.requestkey = arguments.requestkey>
<cfset setDateService(CreateObject("component","dateService").init(this,variables.requestkey))>
<cfset setTranslationService(CreateObject("component","translationService").init(this,variables.requestkey))>
<cfreturn this />
</cffunction>
<cffunction name="getTest1Service">
<cfreturn variables.test1Service />
</cffunction>
<cffunction name="setTest1Service">
<cfargument name="service" type="component">
<cfset variables.test1Service = arguments.service>
</cffunction>
<cffunction name="Foo">
<cfset var result = getTest1Service().Foo()>
<cfreturn result />
</cffunction>
<cffunction name="Bar">
<cfset var result = "bar">
<cfreturn result />
</cffunction>
</cfcomponent>
<cfcomponent displayname="test3Service" accessors="true">
<cfproperty name="test1Service" type="struct">
<cffunction name="init">
<cfargument name="service" type="struct">
<cfargument name="requestkey" type="struct">
<cfset variables.service = arguments.service>
<cfset variables.requestkey = arguments.requestkey>
<cfset setTest1Service(CreateObject("component","test1Service").init(this,variables.requestkey))>
<cfreturn this />
</cffunction>
<cffunction name="Foo">
<cfset var result = "foo">
<cfreturn result />
</cffunction>
<cffunction name="Bar">
<cfset var result = getTest1Service().Bar()>
<cfreturn result />
</cffunction>
</cfcomponent>
<cfset foo = request.lckservicefactory.test1Service.Foo()>
<cfset bar = request.lckservicefactory.test2Service.Bar()>
#foo# #bar#
<cfset foo = request.lckservicefactory.test2Service.Foo()>
<cfset bar = request.lckservicefactory.test1Service.Bar()>
#foo# #bar#
<cfset foo = request.lckservicefactory.test3Service.Foo()>
<cfset bar = request.lckservicefactory.test3Service.Bar()>
#foo# #bar#
<cffunction name="getTest2Service">
<cfif StructKeyExists(variables,"test2Service") AND IsObject(variables.test2Service)>
<cfreturn variables.test2Service />
<cfelse>
<cfset setTest2Service(CreateObject("component","test2Service").init(this,variables.requestkey)) />
<cfreturn variables.test2Service />
</cfif>
</cffunction>