alibaba/QLExpress
QLExpress is a powerful, lightweight, dynamic language for the Java platform aimed at improving developers’ productivity in different business scenes.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓7 active contributors
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 78% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/alibaba/qlexpress)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/alibaba/qlexpress on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: alibaba/QLExpress
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/alibaba/QLExpress shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 7 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 78% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live alibaba/QLExpress
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/alibaba/QLExpress.
What it runs against: a local clone of alibaba/QLExpress — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in alibaba/QLExpress | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of alibaba/QLExpress. If you don't
# have one yet, run these first:
#
# git clone https://github.com/alibaba/QLExpress.git
# cd QLExpress
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of alibaba/QLExpress and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "alibaba/QLExpress(\\.git)?\\b" \\
&& ok "origin remote is alibaba/QLExpress" \\
|| miss "origin remote is not alibaba/QLExpress (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/main/java/com/alibaba/qlexpress4/Express4Runner.java" \\
&& ok "src/main/java/com/alibaba/qlexpress4/Express4Runner.java" \\
|| miss "missing critical file: src/main/java/com/alibaba/qlexpress4/Express4Runner.java"
test -f "src/main/java/com/alibaba/qlexpress4/aparser/QLExtendParser.java" \\
&& ok "src/main/java/com/alibaba/qlexpress4/aparser/QLExtendParser.java" \\
|| miss "missing critical file: src/main/java/com/alibaba/qlexpress4/aparser/QLExtendParser.java"
test -f "src/main/antlr4/QLParser.g4" \\
&& ok "src/main/antlr4/QLParser.g4" \\
|| miss "missing critical file: src/main/antlr4/QLParser.g4"
test -f "src/main/java/com/alibaba/qlexpress4/aparser/QvmInstructionVisitor.java" \\
&& ok "src/main/java/com/alibaba/qlexpress4/aparser/QvmInstructionVisitor.java" \\
|| miss "missing critical file: src/main/java/com/alibaba/qlexpress4/aparser/QvmInstructionVisitor.java"
test -f "src/main/java/com/alibaba/qlexpress4/runtime/QContext.java" \\
&& ok "src/main/java/com/alibaba/qlexpress4/runtime/QContext.java" \\
|| miss "missing critical file: src/main/java/com/alibaba/qlexpress4/runtime/QContext.java"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/alibaba/QLExpress"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
QLExpress is an embedded Java dynamic scripting engine (v4 built on ANTLR4) that allows non-programmers to safely define and execute business rules and expressions. It provides a lightweight DSL with native JSON support, expression tracing for debugging rule execution paths, and first-class function support—enabling business platforms (e-commerce rules, form builders, workflow engines) to let users dynamically configure logic without Java recompilation. Monolithic single-artifact layout: src/main/antlr4/ holds QLexer.g4 and QLParser.g4 grammar definitions; src/main/java/com/alibaba/qlexpress4/ contains the runtime (Express4Runner, QLResult), parser/visitor infrastructure (aparser/ with CheckVisitor, GeneratorScope), and annotation-driven function registration (@QLFunction, @QLAlias). Tests and examples are typically in src/test/ (not detailed in file list).
👥Who it's for
Platform engineers at enterprises (Alibaba, fintech, e-commerce) who build rule configuration systems and need to let business users define discount rules, workflow conditions, or form validation logic safely. Also Java backend developers integrating a lightweight expression language without the overhead of full scripting engines.
🌱Maturity & risk
Actively developed and production-grade. The project dates to 2012 (Alibaba origin), has a complete v4 rewrite on ANTLR4, Maven CI/CD via GitHub Actions (unittest.yml, maven-publish.yml), and Java 815K LOC codebase. Currently at v4.1.0 with ongoing maintenance; the branch_version_3.x.x exists for legacy support, signaling intentional versioning strategy.
Relatively low risk for production use given Alibaba backing and long history, but watch for: ANTLR4 dependency chain (35K+ LOC grammar files), single maintainer (tianqiao@alibaba-inc.com listed prominently in pom.xml), and potential JVM security implications (the engine interprets untrusted scripts—requires careful InitOptions and ClassSupplier configuration). No public issues/PR data visible to assess response time.
Active areas of work
Latest stable is v4.1.0 (pom.xml). Active workflows include unittest.yml and maven-publish.yml, indicating CI validation on each commit. README mentions v4 as 'latest evolution' with emphasis on expression tracing and JSON native support—no visible PRs/milestones in provided data, but the rewrite to ANTLR4 and feature additions (string interpolation, attachments, functional programming) represent the current focus.
🚀Get running
git clone https://github.com/alibaba/QLExpress.git
cd QLExpress
mvn clean install
mvn test
Pom.xml defines standard Maven lifecycle; no special build steps. Requires JDK 8+.
Daily commands:
This is a library, not an application. Include in your Maven project as a dependency (pom.xml snippet in README). To test locally: mvn test. To use in code:
Express4Runner runner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
Map<String,Object> context = new HashMap<>();
context.put("x", 5);
QLResult result = runner.execute("x + 3", context, null);
System.out.println(result.getResult()); // 8
🗺️Map of the codebase
src/main/java/com/alibaba/qlexpress4/Express4Runner.java— Main entry point for executing QLExpress scripts; every contributor must understand the execution pipeline and public APIsrc/main/java/com/alibaba/qlexpress4/aparser/QLExtendParser.java— Core ANTLR4-based parser that transforms scripts into syntax trees; critical for understanding expression parsing and compilationsrc/main/antlr4/QLParser.g4— ANTLR4 grammar definition that defines the entire QLExpress language syntax; any language feature addition starts heresrc/main/java/com/alibaba/qlexpress4/aparser/QvmInstructionVisitor.java— Visitor pattern implementation that generates VM instructions from parsed syntax tree; essential for understanding code generationsrc/main/java/com/alibaba/qlexpress4/runtime/QContext.java— Runtime execution context managing variables, scope, and execution state; necessary for understanding script execution semanticssrc/main/java/com/alibaba/qlexpress4/aparser/OperatorFactory.java— Factory for creating and managing operators; core for extending the language with custom operatorssrc/main/java/com/alibaba/qlexpress4/exception/QLException.java— Base exception hierarchy for the language; important for understanding error handling and reporting strategy
🛠️How to make changes
Add a Custom Function
- Create a public method in any class and annotate it with @QLFunction from src/main/java/com/alibaba/qlexpress4/annotation/QLFunction.java (
Your custom class (e.g., com.example.MyFunctions.java)) - In Express4Runner initialization, register your function class using addFunctionClass() or addFunction() methods (
src/main/java/com/alibaba/qlexpress4/Express4Runner.java) - Call the function in your QLExpress script using the function name (optionally aliased via @QLAlias) (
Your QLExpress script (.qexpress or string))
Add a Custom Operator
- Implement the operator logic by creating a method annotated with @QLFunction with the operator pattern (e.g., 'op_myop') (
Your custom class with operator method) - Register operator metadata using OperatorFactory.addOperator() with precedence and associativity settings (
src/main/java/com/alibaba/qlexpress4/aparser/OperatorFactory.java (view reference) → call in initialization) - Configure operator check strategy via InitOptions.operatorCheckStrategy to allow/deny the operator (
src/main/java/com/alibaba/qlexpress4/InitOptions.java)
Enable Expression Tracing for Debugging
- Set QLOptions.isEnableTracing(true) when creating execution options (
src/main/java/com/alibaba/qlexpress4/QLOptions.java) - Execute the script and extract trace data from QLResult.getTraceMap() which contains intermediate values (
src/main/java/com/alibaba/qlexpress4/QLResult.java) - Trace points are collected via TraceExpressionVisitor during compilation (
src/main/java/com/alibaba/qlexpress4/aparser/TraceExpressionVisitor.java)
Customize Error Reporting & Diagnostics
- Implement the ErrorReporter interface with custom error handling logic (
src/main/java/com/alibaba/qlexpress4/exception/ErrorReporter.java (view reference) → create YourErrorReporter.java) - Pass your ErrorReporter instance via InitOptions.errorReporter() (
src/main/java/com/alibaba/qlexpress4/InitOptions.java) - For IDE/LSP integration, retrieve LSP diagnostics from exceptions or compile check results (
src/main/java/com/alibaba/qlexpress4/exception/lsp/Diagnostic.java)
🪤Traps & gotchas
Sandboxing is opt-in: DefaultClassSupplier allows broad reflection by default; must customize ClassSupplier for secure multi-tenant scenarios (README mentions 'default safe' but requires explicit configuration). ANTLR4 regeneration: modifying grammar requires running Maven build or IDE ANTLR plugin, else parser will not reflect changes. Context variables only: QL cannot directly reference static fields or methods outside context map—must be explicitly passed in (by design for safety). No debug breakpoints: interpreter-only, no step-through debugging; tracing via QLResult.getTrace() and PrintVisitor instead. Token stream caching: AliasTokenSource/AliasTokenStream suggest keyword aliasing support that may silently fail if misconfigured.
🏗️Architecture
💡Concepts to learn
- ANTLR4 Visitor Pattern — QLExpress v4 uses ANTLR4's visitor API (CheckVisitor) to traverse the parse tree; understanding visitor vs. listener patterns is essential for extending the interpreter
- Symbol Table & Scope Management — GeneratorScope and ExistStack manage variable bindings and scope chain during rule execution; critical for multi-level function calls and nested contexts
- Expression Attribution / Tracing — QLExpress uniquely exposes intermediate values of sub-expressions (via QLResult trace); enables root-cause analysis of rule failures—a differentiator from other DSLs
- DSL (Domain-Specific Language) — QLExpress is explicitly a DSL for business rules, not a general-purpose language; understanding DSL principles (grammar design, semantic analysis) guides safe extension
- Sandboxing & ClassLoader Control — ClassSupplier interface restricts reflection access; essential for secure multi-tenant rule execution where untrusted users define scripts
- Lambda & Functional Programming in Interpreters — QLExpress v4 elevates functions to first-class citizens (lambda expressions, higher-order functions); requires careful runtime value representation and closure support
- String Interpolation (Template Literals) — QLExpress supports
${expression}syntax in strings; requires lexer/parser coordination to embed arbitrary expressions inside string tokens
🔗Related repos
alibaba/QLExpress— This is the repo being documented (branch_version_3.x.x is the legacy v3 branch of the same project)beanshell/beanshell— Java scripting engine; QLExpress is lighter and DSL-focused, whereas BeanShell is closer to full Java subset executionoracle/graal— GraalVM polyglot engine; heavier, multi-language, but also supports Java dynamic language implementation—competitor in terms of JVM language executionantlr/antlr4— The parser generator that v4 is built upon; understanding ANTLR4 internals helps debug grammar or visitor issuesalibaba/druid— Alibaba's SQL parser (also ANTLR-based); similar Alibaba ecosystem project for rule/expression evaluation in data pipelines
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for ANTLR4 parser edge cases (QLexer.g4 and QLParser.g4)
The repo has recently migrated to ANTLR4 for the parsing engine (QLExpress4), but there's no visible test coverage for the lexer and parser grammar rules. This is critical for a dynamic language that needs to handle various syntax edge cases, operator precedence, and error scenarios. Tests should cover JSON literals, string interpolation modes, custom operators, and macro definitions that are unique to QLExpress.
- [ ] Create src/test/java/com/alibaba/qlexpress4/aparser/QLexerTest.java with tests for token recognition (keywords, operators, literals, identifiers)
- [ ] Create src/test/java/com/alibaba/qlexpress4/aparser/QLParserTest.java with tests for grammar rules including: expressions, function calls, variable attributes (OutVarAttrsVisitor), macro definitions (MacroDefine), and precedence handling (QLPrecedences)
- [ ] Add tests for error cases using QLErrorListener and QLErrorStrategy to verify error messages are descriptive
- [ ] Test InterpolationMode with string interpolation syntax edge cases
Add integration tests for custom function and operator registration workflow
The API exposes BatchAddFunctionResult.java, QLFunction annotation, and QLAlias annotation for registering custom functions, but there's no visible test coverage for the complete workflow. This is a primary use case (mentioned in README as 'DSL capabilities') and needs tests to prevent regressions when refactoring the registration mechanism (OperatorFactory, ParserOperatorManager).
- [ ] Create src/test/java/com/alibaba/qlexpress4/api/FunctionRegistrationTest.java testing @QLFunction annotation parsing and BatchAddFunctionResult registration
- [ ] Add tests for @QLAlias annotation on custom functions and operators
- [ ] Test operator precedence and associativity when registering custom operators via OperatorFactory
- [ ] Create end-to-end tests that: register a custom function → compile an expression using it → execute and verify result
Add unit tests for the expression tracing/debugging feature (TraceExpressionVisitor)
The README highlights 'expression tracing' as a unique feature for 'attribution analysis of calculation results', and TraceExpressionVisitor exists in the codebase, but there are no visible tests verifying this critical debugging capability works correctly. This feature is essential for business rule auditing and should have tests ensuring intermediate node values are properly captured.
- [ ] Create src/test/java/com/alibaba/qlexpress4/aparser/TraceExpressionVisitorTest.java with tests that: compile an expression → execute with tracing enabled → verify intermediate values are captured at each AST node
- [ ] Add tests for complex expressions (nested function calls, conditional operators, loops) to ensure all nodes are traced
- [ ] Test that traced output includes source locations (line/column numbers) for accurate error attribution
- [ ] Create tests verifying traced results work with the QLResult return type for structured output
🌿Good first issues
- Add comprehensive Javadoc comments to src/main/java/com/alibaba/qlexpress4/aparser/GeneratorScope.java—currently undocumented but critical for understanding scope and symbol resolution during rule execution
- Create a test suite (src/test/java/.../ExpressionTracingTest.java) covering the expression tracing feature (QLResult.getTrace()) with 5+ test cases for nested expressions, function calls, and conditional branches—README emphasizes tracing but no visible test file
- Write a 'Security Best Practices' guide in docs/ explaining how to configure ClassSupplier and InitOptions to safely isolate untrusted scripts in multi-tenant scenarios—currently scattered in README with no dedicated doc
⭐Top contributors
Click to expand
Top contributors
- @DQinYuan — 78 commits
- @zhoutao-55 — 11 commits
- @duqinyuan — 6 commits
- @a345560812 — 2 commits
- @yuxwang-wiley — 1 commits
📝Recent commits
Click to expand
Recent commits
0a56637— Merge pull request #438 from yuxwang-wiley/issue-437 (DQinYuan)c461c15— issue437 block 内部指令复制问题 (yuxwang-wiley)d5f60c4— Commit from GitHub Actions (Reduce Adoc) (DQinYuan)972cd65— fix *. doc format (DQinYuan)6243e60— Commit from GitHub Actions (Reduce Adoc) (DQinYuan)1dba8a2— 4.1.0 (DQinYuan)c297a7c— Commit from GitHub Actions (Reduce Adoc) (DQinYuan)2915f9c— reduce with version replace (DQinYuan)4302c83— Commit from GitHub Actions (Reduce Adoc) (DQinYuan)7065542— auto version (DQinYuan)
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.