Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Issue with implicit accessors

New Here ,
Jan 21, 2019 Jan 21, 2019

Our development team recently discovered that we are getting multiple errors when using implicit get accessor (person.firstName) instead of generated get accessor (person.getFirstName()). Here are instructions of how to reproduce the error:

1. Create a new ColdFusion application with the following files:

Application.cfc:

<cfcomponent output="false">

    <cfset this.invokeImplicitAccessor = true />

</cfcomponent>

Person.cfc:

component accessors=true {

    property firstName;

}

index.cfm:

<cfscript>

    local.person = new Person();

    local.person.firstName = "Zachary";

    for( local.i = 0; local.i < 1000; local.i++ ) {

        local j = local.person.firstName;

    }

</cfscript>

index2.cfm:

<cfscript>

    local.person = new Person();

    local.person.firstName = "Zachary";

    for( local.i = 0; local.i < 1000; local.i++ ) {

        local j = local.person.firstName;

    }

</cfscript>

2. Test the index.cfm with JMeter, use 2000 threads, 10s Ram-Up Period and Loop count 1 (test plan: https://pastebin.com/nBtpL4zP)

3. In our tests the page always fails with the same error message:

Element PERSON.FIRSTNAME is undefined in LOCAL.

4. The error % we are getting with the above settings usually falls somewhere between 8 to 10 %, meaning that 160 to 200 requests out of >2000 requests fails.

5. When index2.cfm gets tested with the same settings, we don't get any errors

Here are some details about the test environment:

OS: Windows Server 2016 Standard

ColdFusion: Adobe ColdFusion 2018 Release

JMeter 5.0 (https://jmeter.apache.org/download_jmeter.cgi)

Does anyone have any idea why this is happening? Is there some ColdFusion settings we could tweak? The above example application is >very minimal, and we are not doing anything special, so I don't see any reasons why implicit accessors should fail, especially when >generated accessors seems to pass the same test without any issues.

We appreciate any help or suggestions of what to try to get the >implicit accessors working.

br,

Antti Koskenalho

2.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 01, 2019 Feb 01, 2019

I tested with this:

component accessors=true {

    property firstName; 

    property age;

}

With first example I'm able to call person.setFirstName( "Zachary" ).setAge( 30 ) without any errors, which makes sense to me, as the fist method call returns the Person object, and I can call it's setAge() method. With your example i also get returntype any and it fails with error Value must be initialized before used.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 01, 2019 Feb 01, 2019

Have you tried using his explicit setters, as he proposed today and previously on Jan 26. I hoped you would have then,at least to see if it made your error go away under the load test. it may not be the preferred solution, but it could be a workaround until the problem was understood.

BTW, whether it's a bug or not still is not clear. A race condition may not be a "bug" in CF, per se, but an unexpected result due to some characteristic of your environment. Still, it's indeed worth filing as an issue in the tracker, to see if Adobe or anyone else can recreate it or not. You ought to also point them to this thread, to see all the things discussed and considered so far.


/Charlie (troubleshooter, carehart. org)
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 01, 2019 Feb 01, 2019

Charlie Arehart​,

I haven't tried with explicit setters, as we ended up using generated accessors presented in index2.cfm implementation as a workaround. However, I do see value in using explicit setters as well, if they work. I could try that next week as well.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 01, 2019 Feb 01, 2019

soltiger  wrote

I tested with this:

component accessors=true {

    property firstName; 

    property age;

}

With first example I'm able to call person.setFirstName( "Zachary" ).setAge( 30 ) without any errors, which makes sense to me, as the fist method call returns the Person object, and I can call it's setAge() method.

It should work, of course. There's no questioning that. What I question is whether it is good practice.

If setFirstName() returns a type, then the object model will be confusing. For example, you might as well forget the terms getters and setters. For setFirstName() is at once mutator as well as accessor.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 01, 2019 Feb 01, 2019

I found this about Method chaining:

ColdFusion Help | Method chaining for CFC methods

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 01, 2019 Feb 01, 2019

soltiger  wrote

I found this about Method chaining:

ColdFusion Help | Method chaining for CFC methods

I am aware of this example. I am not one for dogma, but would suggest you use method-chaining sparingly. Here you are 'setting' properties that are just simple values. But, in general, the properties may be complex objects that themselves contain properties.

Complexity is the reason why you should use method-chaining in moderation. As it may introduce unnecessary coupling to your code. Which will make your software less versatile and, in the long run, more difficult to maintain.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 24, 2019 Jan 24, 2019

On second thoughts, you should not use

local.j=local.person.firstName;

It may work sometimes, but it is, strictly speaking, wrong. That is because firstName is a private field of Person and is in Person's variables scope. So the correct expression is

local.j=local.person.getFirstName();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 24, 2019 Jan 24, 2019

Best to my understanding, and based on the Adobe documentation (ColdFusion Help | CFC Implicit notation), implicit getters and settings should be supported by ColdFusion, and so far I haven't seen any documentation stating that we shouldn't use them. Internally CF invokes the property's get() and set() methods (see Adobe's example) when dot notation is used. However, to rule out the possibility that the generated accessors ( generated by using "accessors=true" in componen cfc ) fails, I tried to manually define the getFirstName() and setFirstName() methods as they have done it in that example. There was no difference when compared to generated accessors.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 26, 2019 Jan 26, 2019

soltiger​, your approach is correct. I reread from the beginning and saw that you had, correctly, defined invokeImplicitAccessor in Application.cfc.

I may not be a fan of the attribute invokeImplicitAccessor, but I should add that my statement

On second thoughts, you should not use

local.j=local.person.firstName;

It may work sometimes, but it is, strictly speaking, wrong.

is just opinion. It comes after I encountered situations where ColdFusion confused accessors(getters) with mutators(setters), making implicit properties behave as if they were keys in a structure. In fact, I am wondering whether you too have stumbled on something similar.

In any case, the main reason I don't use ColdFusion's implicit accessor is that it breaks some fundamental rules in object-oriented design. For example, encapsulation and separation of concerns. Nevertheless, it is a handy feature, as it is flexible.

If you must use invokeImplicitAccessor=true, bear in mind that:

  • personObject.firstName can mean personObject.getFirstName() or personObject.setFirstName(), depending on the context.

"Implicit" means that you and I don't know what ColdFusion is doing under the hood. But here's one clue: the return statement.

Add a setter and a getter to Person.cfc, and test with the following code

<cfscript>

component accessors=true {

    property name="firstName";

 

    function setFirstName(string fName){

        writeOutput("#getFunctionCalledName()# called. <br>");

        variables.firstName = arguments.fName;

    }

    function getFirstName(){

        writeoutput("#getFunctionCalledName()# called. <br>");

        // If you leave out the following line, you will reproduce the error

        return variables.firstName;

    }

}

</cfscript>

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 01, 2019 Feb 01, 2019

Plese find the bug report I just created from here: Tracker https://tracker.adobe.com/#/view/CF-4203997

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 19, 2024 Jul 19, 2024

I know this post is from 2019 but I am experiencing the same random failures on version 2021,0,08,330144. I see your bug tracker is closed as cannot reproduce so I thought I would ask if there was a solution that worked for you. I have attached my reproducible test case, fails randomly and way more often on prod than dev or local even with prod and dev being identical.

andmayfi_0-1721403982880.png

Since I cant seem to upload zips to keep it all neat here is the code. 

 

index.cfm

<cftry>
    <cfset uniqueNameToRuleOutCachingIssuesObject = new test.orders.uniqueNameToRuleOutCachingIssues()>
    <cfset uniqueNameToRuleOutCachingIssuesObject.loadInfo()>

    <cfdump var="#getMetadata(uniqueNameToRuleOutCachingIssuesObject)#" expand="false">
    <cfdump var="#uniqueNameToRuleOutCachingIssuesObject#" label="uniqueNameToRuleOutCachingIssuesObject" expand="false">

    <div>
        <cfoutput>
        <p>uniqueNameToRuleOutCachingIssuesObject.testValue : #uniqueNameToRuleOutCachingIssuesObject.testValue#</p>
        </cfoutput>
    </div>

    <cfcatch>
        <br>
        <h4>Exception Thrown:</h4>
        <cfdump var="#uniqueNameToRuleOutCachingIssuesObject#" label="uniqueNameToRuleOutCachingIssues" expand="false">
        <cfdump var="#cfcatch#">
    </cfcatch>
</cftry>

uniqueNameToRuleOutCachingIssues.cfc

component
  invokeImplicitAccessor = true
  accessors = true
  name = 'uniqueNameToRuleOutCachingIssues'
{

  property integer testValue;


  public uniqueNameToRuleOutCachingIssues function init()
  {
    return this;
  }

  public uniqueNameToRuleOutCachingIssues function loadInfo()
  {
    variables.testValue = 1;

    return this;
  }

	public struct function variablesScope()
	{
		return variables;
	}
}

 

As you can see the value exists in the dumb before the value is access and in the dump in the error after it fails to access the value.  

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 20, 2024 Jul 20, 2024
LATEST

@andmayfi , as you yourself say this thread is a number of years old. ColdFusion has moved on.

I would suggest you start a new thread of your own.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources