jbuild 0.1.8

High-performance Java build tool supporting Maven and Gradle
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# Domain-Driven Design Architecture for jbuild

## Overview

jbuild adopts Domain-Driven Design (DDD) principles to create a maintainable, scalable, and test-friendly architecture. This document outlines the bounded contexts, domain models, and architectural patterns used throughout the codebase.

## Core DDD Principles Applied

1. **Ubiquitous Language** - Consistent terminology across code, documentation, and team communication
2. **Bounded Contexts** - Clear boundaries between different domain areas
3. **Entities & Value Objects** - Rich domain models with clear identity semantics
4. **Aggregates** - Consistency boundaries for domain operations
5. **Domain Services** - Business logic that doesn't belong to a single entity
6. **Repositories** - Abstraction for data access and persistence
7. **Domain Events** - Decoupled communication between bounded contexts

## Bounded Contexts

### 1. Build System Context
**Responsibility**: Detect and abstract different build systems (Maven, Gradle)

**Domain Model**:
- **Entities**: None (stateless detection)
- **Value Objects**: 
  - `BuildSystemType` (Maven, Gradle, JBuild)
  - `BuildFile` (path, type)
- **Services**:
  - `BuildSystemDetector` - Detects build system from project structure
  - `BuildExecutor` (trait) - Unified interface for executing builds
- **Anti-Corruption Layer**: 
  - `GoalMapper` - Maps Maven goals ↔ Gradle tasks
  - `PropertyConverter` - Converts Maven ↔ Gradle properties
  - `DependencyNotationConverter` - Converts dependency formats

**Bounded Context Map**:
```
Build System Context
    ↓ (uses)
Maven Context | Gradle Context
```

### 2. Maven Context
**Responsibility**: Maven-specific build system implementation

**Domain Model**:
- **Aggregates**:
  - `MavenProject` (root) - Represents a Maven project with its lifecycle
    - Contains: `Model`, `Build`, `Dependencies`, `Plugins`
    - Invariants: Valid GAV coordinates, valid lifecycle phases
  
- **Entities**:
  - `MavenSession` - Execution session with state
  - `ReactorProject` - Multi-module project with build status
  
- **Value Objects**:
  - `ArtifactCoordinates` (GAV: groupId, artifactId, version)
  - `LifecyclePhase` (Clean, Validate, Compile, Test, Package, etc.)
  - `Scope` (Compile, Test, Runtime, Provided, System, Import)
  - `Model` (POM representation)
  - `Dependency` (dependency declaration)
  
- **Services**:
  - `ModelBuilder` - Builds effective POM from raw POM + parent
  - `ProjectBuilder` - Constructs MavenProject from Model
  - `LifecycleExecutor` - Executes lifecycle phases
  - `MojoExecutor` - Executes plugin goals
  - `DependencyResolver` - Resolves transitive dependencies
  
- **Repositories**:
  - `LocalRepository` (trait) - Local artifact storage
  - `RemoteRepository` - Remote Maven repository access

**Domain Events**:
- `ProjectBuilt`
- `DependencyResolved`
- `LifecyclePhaseCompleted`
- `MojoExecuted`

### 3. Gradle Context
**Responsibility**: Gradle-specific build system implementation

**Domain Model**:
- **Aggregates**:
  - `GradleProject` (root) - Represents a Gradle project
    - Contains: `Tasks`, `Configurations`, `SourceSets`, `Plugins`
    - Invariants: Valid task graph (no cycles), valid configurations
  
- **Entities**:
  - `Task` - Executable unit of work with dependencies
  - `Configuration` - Dependency configuration (api, implementation, etc.)
  
- **Value Objects**:
  - `SourceSet` (main, test, custom)
  - `TaskNode` (task with dependencies)
  - `ConfigurationDependency` (GAV or project dependency)
  - `JavaToolchain` (JDK specification)
  
- **Services**:
  - `GradleExecutor` - Executes Gradle tasks
  - `TaskGraphBuilder` - Builds task dependency graph
  - `ToolchainResolver` - Finds matching JDK installations
  
- **Repositories**:
  - Shares `LocalRepository` with Maven Context
  - `VersionCatalog` - Centralized dependency versions

**Domain Events**:
- `TaskExecuted`
- `ConfigurationResolved`
- `SourceSetCompiled`

### 4. Artifact Context
**Responsibility**: Artifact management and resolution

**Domain Model**:
- **Aggregates**:
  - `Artifact` (root) - Represents a resolved artifact
    - Contains: `ArtifactCoordinates`, file path, metadata
    - Invariants: Coordinates are valid, file exists
  
- **Value Objects**:
  - `ArtifactCoordinates` (groupId, artifactId, version, classifier, extension)
  - `Version` (with comparison logic)
  - `VersionRange` (version constraints)
  
- **Services**:
  - `ArtifactResolver` - Resolves artifacts from repositories
  - `DependencyResolver` - Resolves transitive dependencies
  - `ConflictResolver` - Resolves version conflicts
  - `VersionComparator` - Compares versions semantically
  
- **Repositories**:
  - `LocalRepository` (trait) - Local artifact cache
  - `RemoteRepository` - Remote artifact source

**Domain Events**:
- `ArtifactDownloaded`
- `DependencyConflictResolved`
- `TransitiveDependenciesResolved`

### 5. Compilation Context
**Responsibility**: Java source compilation

**Domain Model**:
- **Aggregates**:
  - `CompilationUnit` (root) - Represents a compilation task
    - Contains: source files, classpath, output directory
    - Invariants: Valid Java sources, valid classpath
  
- **Value Objects**:
  - `Classpath` (ordered list of paths)
  - `SourceFile` (path, package, class name)
  - `CompilerOptions` (source version, target version, encoding)
  
- **Services**:
  - `JavaCompiler` - Invokes javac
  - `SourceDiscovery` - Discovers Java source files
  - `ClasspathBuilder` - Constructs compilation classpath
  
- **Domain Events**:
- `CompilationStarted`
- `CompilationCompleted`
- `CompilationFailed`

### 6. Testing Context
**Responsibility**: Test discovery and execution

**Domain Model**:
- **Aggregates**:
  - `TestSuite` (root) - Collection of test classes
    - Contains: test classes, test results
    - Invariants: Valid test framework (JUnit, TestNG)
  
- **Value Objects**:
  - `TestClass` (class name, test methods)
  - `TestResult` (passed, failed, skipped, duration)
  
- **Services**:
  - `TestDiscovery` - Discovers test classes
  - `TestRunner` - Executes tests
  - `TestReporter` - Generates test reports
  
- **Domain Events**:
- `TestsDiscovered`
- `TestExecuted`
- `TestSuiteCompleted`

### 7. Packaging Context
**Responsibility**: Creating distributable artifacts (JAR, WAR)

**Domain Model**:
- **Aggregates**:
  - `Package` (root) - Represents a packaged artifact
    - Contains: manifest, resources, compiled classes
    - Invariants: Valid manifest, valid structure
  
- **Value Objects**:
  - `Manifest` (main class, classpath, attributes)
  - `PackageType` (JAR, WAR, EAR)
  
- **Services**:
  - `JarPackager` - Creates JAR files
  - `WarPackager` - Creates WAR files
  - `ManifestGenerator` - Generates MANIFEST.MF
  
- **Domain Events**:
- `PackageCreated`
- `ManifestGenerated`

### 8. Plugin Context
**Responsibility**: Plugin loading and execution

**Domain Model**:
- **Aggregates**:
  - `Plugin` (root) - Represents a loaded plugin
    - Contains: descriptor, mojos, dependencies
    - Invariants: Valid descriptor, compatible version
  
- **Entities**:
  - `Mojo` - Executable plugin goal
  
- **Value Objects**:
  - `PluginDescriptor` (GAV, goals, configuration)
  - `PluginConfiguration` (parameters)
  
- **Services**:
  - `PluginRegistry` - Manages loaded plugins
  - `PluginLoader` - Loads plugins from repositories
  - `MojoExecutor` - Executes plugin goals
  
- **Repositories**:
  - Uses `LocalRepository` and `RemoteRepository`

### 9. Configuration Context
**Responsibility**: Project configuration (jbuild.toml, workspace)

**Domain Model**:
- **Aggregates**:
  - `JBuildConfig` (root) - jbuild.toml configuration
    - Contains: package info, dependencies, dev-dependencies
    - Invariants: Valid TOML, valid dependencies
  
- **Value Objects**:
  - `PackageInfo` (name, version, java version)
  - `WorkspaceConfig` (members, resolver settings)
  - `LockFile` (locked dependencies)
  
- **Services**:
  - `ConfigParser` - Parses jbuild.toml
  - `WorkspaceResolver` - Resolves workspace members
  - `LockFileGenerator` - Generates jbuild.lock

### 10. Code Quality Context
**Responsibility**: Code quality checks (linting, formatting)

**Domain Model**:
- **Aggregates**:
  - `LintReport` (root) - Results of linting
    - Contains: violations, file locations
    - Invariants: Valid source files
  
- **Value Objects**:
  - `Violation` (rule, severity, location, message)
  - `CheckstyleRule` (name, configuration)
  
- **Services**:
  - `CheckstyleRunner` - Runs Checkstyle checks
  - `CodeFormatter` - Formats Java code

## Layered Architecture

```
┌─────────────────────────────────────────────────┐
│         Presentation Layer (CLI)                │
│  - cli.rs: Command definitions                  │
│  - runner/: Command implementations             │
│  - ui/: User interface utilities                │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│         Application Layer                       │
│  - Orchestrates domain services                 │
│  - Use cases (build, test, run, etc.)          │
│  - Transaction boundaries                       │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│         Domain Layer                            │
│  - Entities, Value Objects, Aggregates          │
│  - Domain Services                              │
│  - Domain Events                                │
│  - Business logic and invariants                │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│         Infrastructure Layer                    │
│  - Repository implementations                   │
│  - External service adapters                    │
│  - File system, HTTP, process execution         │
└─────────────────────────────────────────────────┘
```

## Domain Model Patterns

### Entities vs Value Objects

**Entities** (have identity, mutable):
- `MavenProject` - identified by GAV coordinates
- `MavenSession` - identified by session ID
- `Task` - identified by name
- `Plugin` - identified by GAV coordinates

**Value Objects** (no identity, immutable):
- `ArtifactCoordinates` - GAV tuple
- `LifecyclePhase` - enum
- `Version` - version string with comparison
- `Classpath` - list of paths
- `Manifest` - manifest content

### Aggregates and Consistency Boundaries

**Aggregate Rules**:
1. Each aggregate has a root entity
2. External objects can only reference the root
3. Invariants are enforced within aggregate boundaries
4. Aggregates are transaction boundaries

**Key Aggregates**:
- `MavenProject` aggregate - ensures valid project state
- `GradleProject` aggregate - ensures valid task graph
- `Artifact` aggregate - ensures valid coordinates and file
- `Plugin` aggregate - ensures valid descriptor and mojos

### Repository Pattern

All repositories implement trait-based interfaces:

```rust
pub trait LocalRepository: Send + Sync {
    fn find_artifact(&self, coords: &ArtifactCoordinates) -> Result<Option<PathBuf>>;
    fn install_artifact(&self, artifact: &Artifact) -> Result<()>;
    fn exists(&self, coords: &ArtifactCoordinates) -> bool;
}
```

**Benefits**:
- Testability (mock implementations)
- Flexibility (swap implementations)
- Separation of concerns (domain vs infrastructure)

### Domain Services

Domain services encapsulate business logic that:
- Doesn't naturally fit in an entity or value object
- Operates on multiple aggregates
- Requires external dependencies

**Examples**:
- `DependencyResolver` - resolves transitive dependencies
- `ConflictResolver` - resolves version conflicts
- `ModelBuilder` - builds effective POM from inheritance
- `TaskGraphBuilder` - builds task dependency graph

## Anti-Corruption Layers

### Maven ↔ Gradle Translation

The `build` module provides anti-corruption layers:

- `GoalMapper` - translates Maven goals to Gradle tasks and vice versa
- `PropertyConverter` - converts property names between systems
- `DependencyNotationConverter` - converts dependency formats
- `ScopeMapper` - maps Maven scopes to Gradle configurations

This prevents Maven concepts from leaking into Gradle context and vice versa.

## Testing Strategy

### Unit Tests
- Test domain logic in isolation
- Use mock repositories and services
- Focus on invariants and business rules

### Integration Tests
- Test aggregate boundaries
- Test repository implementations
- Test service orchestration

### Domain Model Tests
- Test entity behavior
- Test value object equality and comparison
- Test aggregate invariants

## Migration Path

### Current State
The codebase has implicit DDD patterns but lacks explicit structure.

### Target State
1. **Explicit bounded contexts** - Clear module boundaries
2. **Rich domain models** - Entities with behavior, not anemic models
3. **Domain events** - Decoupled communication
4. **Repository abstractions** - All data access through repositories
5. **Application services** - Orchestrate use cases

### Migration Steps
1. ✅ Identify bounded contexts (completed)
2. ⏳ Extract value objects from primitives
3. ⏳ Define aggregate roots and boundaries
4. ⏳ Implement domain services
5. ⏳ Add domain events
6. ⏳ Refactor to layered architecture

## Benefits of DDD for jbuild

1. **Maintainability** - Clear separation of concerns
2. **Testability** - Mock-friendly interfaces
3. **Extensibility** - Easy to add new build systems
4. **Domain clarity** - Code reflects business concepts
5. **Team alignment** - Ubiquitous language
6. **Reduced coupling** - Bounded contexts prevent tight coupling

## References

- Eric Evans - "Domain-Driven Design: Tackling Complexity in the Heart of Software"
- Vaughn Vernon - "Implementing Domain-Driven Design"
- Martin Fowler - "Patterns of Enterprise Application Architecture"