DefaultExpressionSerializer implements ExpressionSerializer { @Override public String serialize(Expression expr) { try { ByteArrayOutputStream output = new ByteArrayOutputStream(); ObjectOutputStream objectOutput = new ObjectOutputStream(output); objectOutput.writeObject(expr); objectOutput.flush(); return Base64.getEncoder().encodeToString(output.toByteArray()); } catch (IOException e) { throw new IllegalStateException("Failed to serialize expression: " + expr, e); } }  @Override String serialize(Expression expr); @Override Expression deserialize(String code);  }
@Test public void cannot_serialize_illegal_expression() { Expression illegalExpr = new Expression() { private final Object object = new Object(); @Override public ExprValue valueOf(Environment<Expression, ExprValue> valueEnv) { return null; } @Override public ExprType type() { return null; } @Override public <T, C> T accept(ExpressionNodeVisitor<T, C> visitor, C context) { return null; } }; assertThrows(IllegalStateException.class, () -> serializer.serialize(illegalExpr)); }