cel-java icon indicating copy to clipboard operation
cel-java copied to clipboard

[Question] How to make my custom Java POJOs known to CelCompiler?

Open antimatter84 opened this issue 5 months ago • 1 comments

Hi all, I am trying to run expressions against my Java data structure. I find it rather difficult to make my Java objects known to the CelCompiler and documentation seems to be sparse. Here's some code as an exampe:

abstract class MagicalCreature {
  String name;
}

class Dragon extends MagicalCreature {
  String color;
}

class Niffler extends MagicalCreature {
  int pouchVolume;
}

class Suitcase {
  List<MagicalCreature> creatures;
}

class CreatureEvaluator {
  public void evaluate() {
    Suitcase suitcase = ...
    String rule = "suitecase.creatures.exists(c, c.color == 'green')";

    CelCompiler cel = CelCompilerFactory
        .standardCelCompilerBuilder()
        .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
        .setContainer(...)  // required?
        .addVar("suitcase", StructTypeReference.create(Suitcase.class.getName()))
        .setResultType(SimpleType.BOOL)
        .build();


    CelValidationResult compileResult = cel.compile(rule);
    CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder().build();
    CelRuntime.Program program = celRuntime.createProgram(compileResult.getAst());
    Object result = program.eval(Map.of("suitcase", suitcase));
    
    // ...
  }
}

This attempt won't run because with this setup, the compiler doesn't know the "creatures" attribute in the suitcase and it also has no idea about the MagicalCreature subclasses and their members.

I problably need to do something with CelVarDecl, Decl and/or Types.

In my real use case, my input object has deep nesting with lists and maps, containing dozens of such polymorphic objects.

Can someone provide a few tips please, how to properly tell the CelCompiler, what my actual types are? Any help is very much appreciated.

antimatter84 avatar Aug 08 '25 13:08 antimatter84

As of now, your best bet is to either:

  1. Define your schema using protobuf and adapt your POJO into it. You could then evaluate on the proto messages (recommended but some work involved)
  2. Serialize your POJOs into a JSON string, then follow this codelab exercise (easy, but comes with many limitations, including but not limited to type-checking support)

Seamless handling of complex POJOs has been a missing feature in CEL-Java for a while. If you really wanted to, you could follow the example here to provide a custom type/value provider to inform CEL about how to handle your objects, but note that usage of CelValue is currently experimental.

Our eventual goal is to offer something like cel-go's native extension to handle automatic registration of your types and values

l46kok avatar Aug 08 '25 19:08 l46kok