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

Issue with implicit accessors

New Here ,
Jan 21, 2019 Jan 21, 2019

Copy link to clipboard

Copied

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

Views

1.1K

Translate

Translate

Report

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

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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)

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

I found this about Method chaining:

ColdFusion Help | Method chaining for CFC methods

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

LATEST

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.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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();

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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>

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

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
Documentation