TrigerSoft/jaque

Parsing lambda expression with variables does not work

kikogatto opened this issue · 6 comments

Hi,
I am trying to use Jaque to parse a SerializablePredicate in order to build a MongoDB query.

It works fine like this:
LambdaExpression<SerializablePredicate> ex = LambdaExpression.parse(t -> t.getName() == "Maria Bonita");

Or even like this:
public void testExpression2() {
this.testExpression(t -> t.getName() == "Maria Bonita");
}
protected void testExpression(SerializablePredicate p) {
final LambdaExpression<SerializablePredicate> ex = LambdaExpression.parse(p);
assertNotNull(ex);
}

But if I try to use name as a String variable, it will not work AND try to parse from the file system, throwing a misleading exception;

Attached is a JUnit test file that will show what I mean. Just run the tests.
Ops, turns out I cant attach .java files. The code is bellow:


/**
*
*/
package commons.queries;

import static org.junit.Assert.assertNotNull;

import java.io.Serializable;
import java.util.function.Predicate;

import org.junit.Test;

import com.trigersoft.jaque.expression.LambdaExpression;

/**

  • @author gatto
    */
    public class SerializablePredicateTest {

    @test
    public void testExpression1() {
    final LambdaExpression<SerializablePredicate> ex = LambdaExpression.parse(t -> t.getName() == "Maria Bonita");
    assertNotNull(ex);
    }

    @test
    public void testExpression2() {
    this.testExpression(t -> t.getName() == "Maria Bonita");
    }

    @test
    public void testExpression3() {
    final String name = "Maria Bonita";
    this.testExpression(name);
    }

    @test
    public void testExpression4() {
    this.testExpression("Maria Bonita");
    }

    protected void testExpression(final String name) {
    this.testExpression(t -> t.getName() == name);
    }

    protected void testExpression(SerializablePredicate p) {
    final LambdaExpression<SerializablePredicate> ex = LambdaExpression.parse(p);
    assertNotNull(ex);
    }
    }

interface SerializablePredicate extends Predicate, Serializable {

}

class Person {
private String name;

/**
 * @return the name
 */
public String getName() {
    return this.name;
}

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

}

The tests above were added to the suite and all passed. Please see the commit above for details. Hence closing the issue. Please add more information if the problem still exists.

Hey,
thanks for the quick answer.
They will only work with the jdk.internal.lambda.dumpProxyClasses property set.
The tests will not pass without the configuration bellow, even if the lambdas are Serializable.

            <configuration>
                <systemPropertyVariables>
 <jdk.internal.lambda.dumpProxyClasses>${HOME}/lambda</jdk.internal.lambda.dumpProxyClasses>
                </systemPropertyVariables>
            </configuration>

It is meant to work without the property if the lambda is Serializable, right?

The issue is fixed with side note that the wrapping LambdaExpression misses the captured arguments. Since the Body is correct and only it's important for tree analysis, I consider the issue minor. A separate issue #6 is created. Let me know if this is OK in your case.

Hey,
My usecase is building a query for MongoDB based on a Predicate.
Something like :

User user = userRepository.findByUsername(username); // username is a String received as argument

User findByUsername(String username) {
    LambdaExpression<SerializablePredicate<User>> ex = LambdaExpression.parse(t -> t.getUsername() == username);
    Bson query = ex.accept(bsonVisitor)
    return this.collection.find(bson).first();
}

Therefore I need to be able to parse a SerializablePredicate with variable arguments.

Can you point me towards the solution? I will be happy to try and fix it.

Jaque is needed when the query is not known at design time, i.e. if you know that the query is user.getUsername() == username, code that directly with mongoDB tools! So your sample is not clear...

In any case with my latest commit I fixed the issue with SerializedPredicate and you can parse it and analyze its expression tree without dumpProxyClasses property set.

With the #6 fix all works correctly now.