Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class Method Executed Twice #333

Open
MichaelPastuch opened this issue Jun 27, 2023 · 2 comments
Open

Class Method Executed Twice #333

MichaelPastuch opened this issue Jun 27, 2023 · 2 comments

Comments

@MichaelPastuch
Copy link

I have encountered some strange scenarios where class methods appear to be executed twice, but only in statements where a new class is instantiated and the method is run.

Consider Foo.java

package org.example;

public class Foo {

    static Integer barCount = 0;
    static Integer bazCount = 0;
    static Integer quxCount = 0;

    public String bar() {
        barCount++;
        return "bar";
    }

    public void baz() {
        bazCount++;
    }

    public Integer qux() {
        quxCount++;
        return null;
    }

}

And a basic Main.java

package org.example;

import org.mvel2.MVEL;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {

        var vars = new HashMap<String, String>();
        vars.put("foo", "initial");

        var compiledMvel = MVEL.compileExpression("""
            import org.example.Foo;
            foo = new Foo().bar();
            new Foo().baz();
            new Foo().qux();

            localFoo = new Foo();
            localFoo.bar();
            localFoo.baz();
            localFoo.qux();
        """);
        MVEL.executeExpression(compiledMvel, vars);

        System.out.println(vars.get("foo"));
        System.out.println(Foo.barCount);
        System.out.println(Foo.bazCount);
        System.out.println(Foo.quxCount);
    }
}

I would expect methods bar, baz, and qux to each be called 2 times, but baz and qux have been called 3 times.

        new Foo().baz();
        new Foo().qux();

These two lines result in their methods being called twice.

@scmod
Copy link

scmod commented Sep 18, 2023

it seem this condition cause the problem
NewObjectNode.getReducedValueAccelerated
it's commented
/** * Check to see if the optimizer actually produced the object during optimization. If so, * we return that value now. */
so if called in chain like new Foo().baz(); and baz() return value is null or void type
it will treat as optimizer actually not produced the object during optimization, and call newObjectOptimizer.getValue(ctx, thisValue, factory) later.
as a workaround, we can call foo = new Foo(); and then foo.baz()
or remove the optimizer.getResultOptPass() condition maybe ok?

@MichaelPastuch
Copy link
Author

Sounds good. I've used the workaround approach in a few places, but I feel like the optimizer should be aware of "side effects" from constructors and methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants