Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rules_jena

API reference, generated from the module’s .bzl docstrings (stardoc).


rules_jena roadmap

Three releases get from “scaffold” to a full Jena-backed implementation of every rules_rdf toolchain type, plus a small set of user-facing convenience rules. Each row points at the production pattern in ~/Documents/rfcs/kg/java/ that gets ported; see SOURCES.md for the full catalog.

v0.1 (next)

Stand up the shared library and the first toolchain. Goal: prove rules_rdf’s contract works for a Jena backend end-to-end.

  • Port Loader.java (corpus-loading) and Writer.java (deterministic Turtle) plus their tests (WriterTest.java) into a public :rdf_io java_library at the rules_jena root.
  • Implement one toolchain — the SPARQL engine — as a java_binary registered under rules_rdf’s sparql_engine_toolchain_type:
    • Read the SPARQL query path from argv (--query=...).
    • Read the data graph as Turtle from stdin.
    • Emit results (TSV or JSON) on stdout, diagnostics on stderr, non-zero exit on parse / execution failure.
    • Same shape as the gate_query_smoke target in kg/java/BUILD.bazel.
  • Gate the toolchain binary with rules_rdf’s plugin-contract conformance test (the analog of jsonschema_plugin_contract_test).
  • Register the default toolchain in MODULE.bazel.
  • Maven coordinates for jena-arq / jena-core / jena-base / jena-iri / slf4j-simple declared inline (no rules_jvm_external pin yet — defer to v0.2 once the full set of binaries is in scope).

v0.2

Round out the toolchain implementations. Goal: every rules_rdf toolchain type has a Jena-backed default.

  • Port GateHarness.java, Gates.java, GateZeroRows.java, GateShacl.java, GateQuerySmoke.java as additional toolchain-backing binaries — one per gate shape.
  • Implement the SHACL validator toolchain on top of org.apache.jena.shacl.ShaclValidator (mirroring GateShacl).
  • Implement the RDF serializer toolchain on top of RDFDataMgr plus the Writer.java invariants.
  • Implement the OWL reasoner toolchain via ReasonerRegistry.getOWLMicroReasoner() (the same call KgReasoner makes in production).
  • Pin Maven artifacts via rules_jvm_external. Single maven.install block in MODULE.bazel; a locked maven_install.json checked in. Removes the hand-rolled @maven//:org_apache_jena_* references that consumers maintain today.
  • Smoke fixture using a tiny pinned ontology (a few classes, a few SHACL shapes, a handful of .rq files) so every toolchain gets an end-to-end test under //examples/smoke.

v0.3

Expose the higher-level patterns the corpus uses every day. Goal: a downstream consumer can replace kg/java/ with a thin BUILD file that loads from rules_jena.

  • Extract kg/lint/ patterns into a reusable jena_lint rule — orphan / consistency checks driven by a user-supplied query set.
  • Extract kg/rules/ patterns into a jena_reason rule — runs a pinned set of Jena rule files over a Dataset and emits a deterministic inferred Turtle output (mirroring kg_reasoner --check).
  • Provide a jena_corpus macro that takes an ontology dir, a TTL glob, a queries dir and stitches together the gate test_suite the corpus uses today.

Source-of-truth patterns to port

The Jena patterns rules_jena packages as toolchains all exist in production today, in the Aion RFC knowledge-graph tree at ~/Documents/rfcs/kg/java/. This file catalogs which files we extract and what each one teaches.

Reference BUILD files (read-only sources of the wiring):

  • ~/Documents/rfcs/kg/java/BUILD.bazel — the JENA_DEPS list, the :loader, :writer, :gate_harness java_library declarations, plus the gate_* java_tests.
  • ~/Documents/rfcs/kg/java/reasoner/BUILD.bazel — the kg_reasoner java_binary (OWL-MICRO inference).

Files

File (under ~/Documents/rfcs/kg/java/)What it teaches
Loader.javaSingle shared library that loads every TTL under a corpus root into one in-memory Jena Dataset. Every downstream binary depends on this — port becomes the public :rdf_io library at the rules_jena root.
Writer.javaDeterministic Turtle serializer. Stable prefix ordering, stable blank-node labels, byte-stable round-trip. The invariants documented in the file header become the rules_jena serializer toolchain’s contract.
WriterTest.javaRound-trip + parse-equivalence test: write(load(write(model))) byte-equals write(model) and the result is isomorphic to the input. Ports as the rules_jena serializer-toolchain conformance test.
GateHarness.javaOrchestrates a set of SPARQL zero-row checks plus a SHACL conformance check against one Dataset. The “compose multiple gates into one suite” pattern.
Gates.javaShared query-plumbing helpers (load a .rq from disk, execute against a Dataset, collect results). Used by every Gate* binary; ports as a private helper for the SPARQL + SHACL toolchain binaries.
GateZeroRows.javaThe “run one .rq and fail if it returns >0 rows” gate shape. Generalizes to the rules_jena SPARQL toolchain’s zero-row mode.
GateQuerySmoke.javaThe “every .rq under a dir parses + executes” gate shape. The conformance-test analog for SPARQL toolchains.
GateShacl.javaThe “load shapes.ttl + data, run ShaclValidator, fail on non-conforming” gate shape. Becomes the rules_jena SHACL validator toolchain core.
reasoner/KgReasoner.javaOWL-MICRO inference via ReasonerRegistry.getOWLMicroReasoner(), plus a Jena rule-file driver. Deterministic, idempotent output. Becomes the rules_jena OWL reasoner toolchain.

What we do not port (yet)

These exist in the kg/java/ tree but are corpus-specific, not generic Jena tooling — they belong in a downstream consumer, not in rules_jena:

  • KgReport.java, CrossCutting.java — Aion-specific reporting.
  • AionPaths.java — XDG/macOS/Windows config paths (not Jena).
  • BuildSummary.javaSUMMARY.md drift gate (not Jena).
  • Anything under kg/java/edit/, kg/java/lint/, kg/java/metrics/, kg/java/research/ — corpus-specific CLIs. The reusable shapes inside them (lint rules, metric formulas) land as jena_lint / jena_reason in v0.3.

jena_dataset(name, default_graph, named_graphs) — a Jena Dataset: a default graph plus a set of named graphs addressable by IRI.

Provider-only. Composes jena_model labels. Like jena_model, also emits RdfDatasetInfo (the union of all triples across the default + named graphs) so rules_rdf rules consume it transparently.

load("@rules_jena//jena:defs.bzl", "jena_model", "jena_dataset")

jena_model(name = "core", srcs = ["core.ttl"], in_format = "turtle")
jena_model(name = "facts", srcs = ["facts.ttl"], in_format = "turtle")
jena_model(name = "claims", srcs = ["claims.ttl"], in_format = "turtle")

jena_dataset(
    name = "corpus",
    default_graph = ":core",
    named_graphs = {
        "http://example.org/g/facts": ":facts",
        "http://example.org/g/claims": ":claims",
    },
)

Datasets without named graphs are a degenerate case — for those, use jena_model directly.

jena_dataset

load("@rules_jena//jena:dataset.bzl", "jena_dataset")

jena_dataset(name, default_graph, named_graphs)

A Jena Dataset composed of named-graph jena_models + an optional default graph.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
default_graphA jena_model whose triples form the dataset’s default graph (unnamed). Optional.LabeloptionalNone
named_graphsMap of graph IRI → jena_model label. Each entry becomes a named graph in the resulting Dataset.Dictionary: String -> Labeloptional{}

Public API surface for rules_jena.

Re-exports the v0.2 user-facing rules (Bazel-idiomatic Jena data primitives) + the JENA_DEPS Maven label set shared with anyone writing their own Jena java_binary.

load("@rules_jena//jena:defs.bzl",
     "JENA_DEPS",
     "jena_model", "jena_dataset", "jena_rule_set", "jena_reasoner",
     "JenaModelInfo", "JenaDatasetInfo", "JenaRuleSetInfo", "JenaReasonerInfo")

Pair with the rules_rdf user-facing test rules (sparql_query_test, rdf_validate_test) — jena_model / jena_dataset emit both JenaModelInfo / JenaDatasetInfo AND RdfDatasetInfo, so they’re drop-in replacements for rdf_dataset in any rules_rdf rule.

rules_jena’s MODULE.bazel auto-registers four toolchains satisfying every rules_rdf toolchain type — pulling in rules_jena is enough to run any of sparql_query_test, rdf_validate_test, rdf_transform, rdf_reason. v0.2’s jena_reason build action is the consumer-facing alternative when a downstream rule wants a concrete file artifact instead of the test-shaped rdf_reason.

jena_dataset

load("@rules_jena//jena:defs.bzl", "jena_dataset")

jena_dataset(name, default_graph, named_graphs)

A Jena Dataset composed of named-graph jena_models + an optional default graph.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
default_graphA jena_model whose triples form the dataset’s default graph (unnamed). Optional.LabeloptionalNone
named_graphsMap of graph IRI → jena_model label. Each entry becomes a named graph in the resulting Dataset.Dictionary: String -> Labeloptional{}

jena_model

load("@rules_jena//jena:defs.bzl", "jena_model")

jena_model(name, srcs, base_iri, in_format)

A Jena Model (single RDF graph) declared as Bazel data.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
srcsSource RDF files for this single graph. Concatenated in lexicographic order by Jena tools.List of labelsrequired
base_iriOptional base IRI for resolving relative references in srcs. Empty = none.Stringoptional""
in_formatSerialization of every file in srcs. Mixed formats aren’t supported — pipe through rdf_transform first if you need to combine.Stringoptional"turtle"

jena_reasoner

load("@rules_jena//jena:defs.bzl", "jena_reasoner")

jena_reasoner(name, profile, rule_set)

A Jena reasoner configuration (provider-only).

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
profileBuilt-in profile name or custom. custom requires rule_set.Stringoptional"rdfs"
rule_setA jena_rule_set label. Required iff profile = ‘custom’.LabeloptionalNone

jena_rule_set

load("@rules_jena//jena:defs.bzl", "jena_rule_set")

jena_rule_set(name, rules)

A set of Jena rule files for the rule-engine reasoner.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
rulesJena rule files. Each must follow the rule-engine syntax at https://jena.apache.org/documentation/inference/#rules.List of labelsrequired

JenaDatasetInfo

load("@rules_jena//jena:defs.bzl", "JenaDatasetInfo")

JenaDatasetInfo(default_graph, named_graphs)

A Jena Dataset (collection of named graphs + an optional default graph). Used by rules that need named-graph addressability (Fuseki, multi-graph SPARQL).

FIELDS

NameDescription
default_graphJenaModelInfo | None: triples that live outside any named graph.
named_graphsdict[str, JenaModelInfo]: graph IRI → model. Order-preserving.

JenaModelInfo

load("@rules_jena//jena:defs.bzl", "JenaModelInfo")

JenaModelInfo(files, in_format, base_iri)

A single Jena Model (RDF graph). Provider-only — the files declared on the rule remain the source of truth.

FIELDS

NameDescription
filesdepset[File]: source files concatenated to form the model.
in_formatstr: serialization (turtle, ntriples, nquads, trig, jsonld, rdfxml). Matches the rules_rdf RDF_FORMATS vocabulary.
base_iristr: optional base IRI for relative references in the source files. Empty string = no base.

JenaReasonerInfo

load("@rules_jena//jena:defs.bzl", "JenaReasonerInfo")

JenaReasonerInfo(profile, rule_set)

A Jena reasoner configuration. Either a built-in profile (rdfs, owl-rl, owl-mini, owl-micro) or a custom rule set; never both. Consumed by jena_reason and by the rdf_reasoner_toolchain_type plugin contract.

FIELDS

NameDescription
profilestr: built-in profile name, or empty if custom.
rule_setJenaRuleSetInfo | None: rule set for the custom profile.

JenaRuleSetInfo

load("@rules_jena//jena:defs.bzl", "JenaRuleSetInfo")

JenaRuleSetInfo(files)

A set of Jena rule files consumed by the rule-engine reasoner (Jena’s RETE-based forward/backward inference). See https://jena.apache.org/documentation/inference/ for the rule syntax. Distinct from SPARQL .rq files.

FIELDS

NameDescription
filesdepset[File]: .rule files in the set.

jena_model(name, srcs, in_format, base_iri) — declare one RDF graph as a Jena-aware data primitive.

Provider-only: no Bazel actions, no parsed-form artifacts. The srcs files remain the source of truth; downstream rules either read them directly or feed them to a Java tool that parses them into an in-memory Model.

Every jena_model ALSO emits RdfDatasetInfo (the abstract provider from rules_rdf) so it’s a drop-in dataset for any rules_rdf rule:

load("@rules_jena//jena:defs.bzl", "jena_model")
load("@rules_rdf//sparql:defs.bzl", "sparql_query_test")

jena_model(
    name = "ontology",
    srcs = ["ontology.ttl"],
    in_format = "turtle",
)

sparql_query_test(  # works: resolves via RdfDatasetInfo
    name = "ontology_well_formed",
    dataset = ":ontology",
    query = "queries/check.rq",
)

For named-graph use cases see jena_dataset.

jena_model

load("@rules_jena//jena:model.bzl", "jena_model")

jena_model(name, srcs, base_iri, in_format)

A Jena Model (single RDF graph) declared as Bazel data.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
srcsSource RDF files for this single graph. Concatenated in lexicographic order by Jena tools.List of labelsrequired
base_iriOptional base IRI for resolving relative references in srcs. Empty = none.Stringoptional""
in_formatSerialization of every file in srcs. Mixed formats aren’t supported — pipe through rdf_transform first if you need to combine.Stringoptional"turtle"

Provider types for the rules_jena public API.

The data primitives (jena_model, jena_dataset, jena_rule_set, jena_reasoner) are provider-only — they carry references to files + small Jena-shaped config, no build actions. Build-action rules (jena_reason, the rules_rdf-driven rdf_validate_test, etc.) consume them.

Every data-providing rule also emits the abstract RdfDatasetInfo from rules_rdf, so jena_model / jena_dataset are drop-in replacements for rdf_dataset in any rules_rdf rule. Consumers who want Jena-aware features (named graphs, rule sets, OWL profiles) reach for the Jena providers; everyone else stays on the abstract interface.

The names use the package-prefixed convention (JenaXInfo) so that an unwrapped JenaModelInfo import is unambiguous next to the rules_rdf RdfDatasetInfo.

JenaDatasetInfo

load("@rules_jena//jena:providers.bzl", "JenaDatasetInfo")

JenaDatasetInfo(default_graph, named_graphs)

A Jena Dataset (collection of named graphs + an optional default graph). Used by rules that need named-graph addressability (Fuseki, multi-graph SPARQL).

FIELDS

NameDescription
default_graphJenaModelInfo | None: triples that live outside any named graph.
named_graphsdict[str, JenaModelInfo]: graph IRI → model. Order-preserving.

JenaModelInfo

load("@rules_jena//jena:providers.bzl", "JenaModelInfo")

JenaModelInfo(files, in_format, base_iri)

A single Jena Model (RDF graph). Provider-only — the files declared on the rule remain the source of truth.

FIELDS

NameDescription
filesdepset[File]: source files concatenated to form the model.
in_formatstr: serialization (turtle, ntriples, nquads, trig, jsonld, rdfxml). Matches the rules_rdf RDF_FORMATS vocabulary.
base_iristr: optional base IRI for relative references in the source files. Empty string = no base.

JenaReasonerInfo

load("@rules_jena//jena:providers.bzl", "JenaReasonerInfo")

JenaReasonerInfo(profile, rule_set)

A Jena reasoner configuration. Either a built-in profile (rdfs, owl-rl, owl-mini, owl-micro) or a custom rule set; never both. Consumed by jena_reason and by the rdf_reasoner_toolchain_type plugin contract.

FIELDS

NameDescription
profilestr: built-in profile name, or empty if custom.
rule_setJenaRuleSetInfo | None: rule set for the custom profile.

JenaRuleSetInfo

load("@rules_jena//jena:providers.bzl", "JenaRuleSetInfo")

JenaRuleSetInfo(files)

A set of Jena rule files consumed by the rule-engine reasoner (Jena’s RETE-based forward/backward inference). See https://jena.apache.org/documentation/inference/ for the rule syntax. Distinct from SPARQL .rq files.

FIELDS

NameDescription
filesdepset[File]: .rule files in the set.

jena_reasoner(name, profile|rule_set) — declare a reasoner configuration.

Provider-only. Either a built-in profile or a custom rule set; the rule rejects both-or-neither.

Built-in profiles map onto Jena’s ReasonerRegistry:

profileJena equivalent
rdfsReasonerRegistry.getRDFSReasoner()
owl-rlReasonerRegistry.getOWLReasoner()
owl-miniReasonerRegistry.getOWLMiniReasoner()
owl-microReasonerRegistry.getOWLMicroReasoner()
customGenericRuleReasoner with the given rule_set.

The Aion production kg_reasoner uses owl-micro plus purpose-written Jena rule files; both shapes have first-class support here.

load("@rules_jena//jena:defs.bzl", "jena_rule_set", "jena_reasoner")

jena_rule_set(name = "kg_rules", rules = glob(["rules/*.rule"]))

jena_reasoner(name = "owl_micro_plus_kg", profile = "custom", rule_set = ":kg_rules")

To actually apply the reasoner to a base model, use jena_reason (which runs a build action) or the abstract rdf_reason rule from rules_rdf (which resolves the reasoner toolchain).

jena_reasoner

load("@rules_jena//jena:reasoner.bzl", "jena_reasoner")

jena_reasoner(name, profile, rule_set)

A Jena reasoner configuration (provider-only).

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
profileBuilt-in profile name or custom. custom requires rule_set.Stringoptional"rdfs"
rule_setA jena_rule_set label. Required iff profile = ‘custom’.LabeloptionalNone

jena_rule_set(name, rules) — a collection of Jena rule files for the rule-engine reasoner.

Provider-only. Consumed by jena_reasoner(profile = "custom") and by the rdf_reasoner_toolchain_type plugin contract when the plugin’s --rules flag points at a file from this set.

Jena rule syntax (the RETE forward-chainer’s input — distinct from SPARQL):

@prefix ex: <http://example.org/> .

[transitiveSubOrg:
    (?a ex:partOf ?b),
    (?b ex:partOf ?c)
    -> (?a ex:partOf ?c)
]

See https://jena.apache.org/documentation/inference/#rules. The file extension is .rule by convention; .txt is tolerated.

jena_rule_set

load("@rules_jena//jena:rules.bzl", "jena_rule_set")

jena_rule_set(name, rules)

A set of Jena rule files for the rule-engine reasoner.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
rulesJena rule files. Each must follow the rule-engine syntax at https://jena.apache.org/documentation/inference/#rules.List of labelsrequired