Authoritative references:
openclaw-java-sdk/pom.xml
Full template:assets/pom-template.xml
Differences from spring-boot-starter-patterns:No parent, does not depend on Spring, aimed at pure Java components
Capability Boundaries
✅ Strong Suits
- Parentless standalone POM — plugin/dependency versions are all self-managed (this is why properties must declare complete plugin versions)
- maven.compiler.release — safer than source/target (--release semantics prevent misuse of higher-version JDK APIs)
- Three metadata sections — licenses/scm/developers (required for Central publishing)
- Multiple JDK branches — feature/{line} one source tree for multiple JDK lines, only pom differences between branches
- Same-line dependencies between components — feature/1.0.x only depends on the 1.0.x line of other components
❌ Out of Scope
- Spring Boot starter (integrating components into SB) → use
spring-boot-starter-patterns - Libraries with strong Spring ecosystem dependencies → should be made into a starter
Errors LLMs most commonly make
| # | Error | Correct approach |
|---|---|---|
| 1 | Adding spring-boot-starter-parent to a standalone component | No parent; plugin versions are self-managed in the third section of properties |
| 2 | java.version write 8 |
write 1.8(under the maven-compiler-plugin 3.15.0 + JDK8 combination, --release 8 has issues;1.8 is compatible across all versions) |
| 3 | Using source/target instead of release | maven.compiler.release=${java.version}(API-safe) |
| 4 | Omitting licenses/scm/developers | Required for Central publishing; add Chinese comments for each section |
| 5 | Cross-line dependencies on internal components | Same-line principle: feature/1.0.x → depends on the 1.0.x line |
| 6 | Source drift between branches | src/tests/README byte-for-byte identical; only pom differences |
| 7 | Compiling release 8 locally with JDK 26 | export JAVA_HOME=$(/usr/libexec/java_home -v 21) |
| 8 | Writing --xxx |
Double hyphens are forbidden inside XML comments (not well-formed) |
| 9 | Thinking the model must be changed under Maven 4 | M4 is compatible with 4.0.0 with zero changes; only upgrade to 4.1.0 for new features such as session scope (buildable only with M4); flatten can be removed (native consumer POM) |
| 10 | Writing versionless Jackson dependency entries in dependencyManagement | A versionless dm entry will shadow the BOM import, causing dependencies.dependency.version is missing; you must delete the dm entry as a whole (you cannot just delete the version line) to let the BOM take effect |
| 11 | Writing the version separately for each Jackson module | Manage uniformly with a BOM: define in properties jackson-bom.version, in dependencyManagement import com.fasterxml.jackson:jackson-bom:${jackson-bom.version}(2.x) or import tools.jackson:jackson-bom:${jackson-bom.version}(3.x); do not write versions in dependencies |
| 12 | Using License URL http:// |
The Apache License URL must use https://www.apache.org/licenses/LICENSE-2.0.txt(http will be rejected by Central) |
| 13 | Inconsistent pom.xml indentation | Uniform 4-space indentation, XML tags aligned, properties grouped in three sections |
Core quick reference
Element order (iron rule)
坐标(无 parent!)→ name/url/description/version/packaging
→ licenses → scm → developers (Central 必需)
→ properties(三段式)→ dependencyManagement → dependencies
→ distributionManagement → build → profiles
Three-part properties
① 基础: java.version / maven.compiler.release / maven.version / encoding
② <!-- Dependency versions --> : 外部依赖 + 内部组件线版本
③ <!-- Maven Plugin versions --> : 完整插件版本(无 parent 全自管)
Jackson BOM version management
When a component depends on Jackson,it must be managed uniformly with the BOM, and each module is forbidden from writing version individually:
properties: jackson-bom.version = {版本}
dependencyManagement:
<dependency>
<groupId>com.fasterxml.jackson</groupId> ← 2.x
<artifactId>jackson-bom</artifactId>
<version>${jackson-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
dependencies: jackson-databind / jackson-dataformat-xml 等(不写 version)
| Branch | jackson-bom.version | groupId |
|---|---|---|
| 1.0.x | 2.18.9 | com.fasterxml.jackson |
| 2.0.x | 2.22.1 | com.fasterxml.jackson |
| 3.0.x | 3.2.1 | tools.jackson |
⚠ Iron rule: in dependencyManagement,placing a Jackson entry without a version is forbidden—it will shadow the BOM import, causing dependencies.dependency.version is missing. The dm entry must be deleted entirely.
Key differences from starter
| Dimension | Component (this skill) | starter |
|---|---|---|
| parent | None | spring-boot-starter-parent |
| Compile | release | source/target |
| Dependencies | May depend on internal component lines | Dependencies on components + SB four-piece set |
| Three-piece set | Client facade + Config + capability domain subpackages | AutoConfiguration+Properties+Template |
| Release order | Lower layers released first → starter released later | Dependent components already released |
Branch model quick reference
| feature/{line} | JDK | java.version | Jackson BOM |
|---|---|---|---|
| 1.0.x | 8 | 1.8 | 2.18.9 (com.fasterxml.jackson) |
| 2.0.x | 17 | 17 | 2.22.1 (com.fasterxml.jackson) |
| 3.0.x ~ 3.5.x | 21 | 21 | 3.2.1 (tools.jackson) |
Version:{line}.x.{yyyyMMdd} ↔ -SNAPSHOT; synchronization method:git checkout <src> -- src/ README.md(excluding pom).
Creation/verification checklist (8 steps)
Copy assets/pom-template.xml → replace placeholders → fill in version/java.version according to the branch (no parent, lombok explicit version) → verify the three-part structure → source three-piece set (Client/Config/capability domain) → test → mvn clean verify → create multiple branches. For the full walkthrough, see examples/create-component.md。
References (load on demand)
| File | When to read |
|---|---|
| references/pom-structure.md | When writing/modifying pom: detailed explanation of the no-parent structure, full three-part structure, build plugin configuration table, four dependency groups |
| references/branch-release.md | When branching/releasing: multi-JDK branch synchronization method, same-line dependencies, 5-step tag release, rolling update |
| references/maven4.md | When building with Maven 4: M3/M4 differences, running JDK 17+, maven.version baseline, consumer POM (native replacement for flatten), wrapper migration |
| examples/create-component.md | 8-step walkthrough for encapsulating a component from scratch |
| examples/maven4-migration.md | When migrating to Maven 4: self-managed plugin comparison, removing flatten (native replacement by consumer POM), three-branch verification, 4.1.0 session scope upgrade assessment |
| assets/pom-template.xml | Maven 3 / model 4.0.0 template (M3/M4 dual-track, XML validation passed) |
| assets/pom-template-maven4.xml | Maven 4 / model 4.1.0 template (enforcer [4.0.0,), session scope example, no flatten) |
Quality gates
- JaCoCo:BUNDLE LINE ≥ 0.90,haltOnFailure=true
- Testing: JUnit 5 (junit-jupiter) + AssertJ
- Javadoc: English; class-level summary + @author/@since; method-level @param/@return