|
| 1 | +# MavenDownloaderImpl Analysis |
| 2 | + |
| 3 | +## Purpose |
| 4 | +`MavenDownloaderImpl` is a pragmatic Maven artifact resolution API that provides a simplified interface for downloading Maven artifacts using Maven Resolver (formerly Aether). It's used across Camel for dependency resolution in JBang, Kamelet Main, and catalog tools. |
| 5 | + |
| 6 | +## Current Implementation (1,240 lines) |
| 7 | + |
| 8 | +### Key Responsibilities |
| 9 | + |
| 10 | +1. **Artifact Resolution**: Download Maven artifacts with optional transitive dependencies |
| 11 | +2. **Version Resolution**: Find available versions of artifacts from repositories |
| 12 | +3. **Repository Configuration**: Configure Maven Central, Apache Snapshots, and custom repositories |
| 13 | +4. **Settings Processing**: Read and process Maven settings.xml and settings-security.xml |
| 14 | +5. **Dual Mode Operation**: |
| 15 | + - **Standalone mode**: Create and configure all Maven Resolver components |
| 16 | + - **Embedded mode**: Use injected components from Maven plugin context |
| 17 | + |
| 18 | +### Current Architecture |
| 19 | + |
| 20 | +#### Fields |
| 21 | +- `RepositorySystem repositorySystem` - Maven Resolver's main entry point |
| 22 | +- `RepositorySystemSession repositorySystemSession` - Session for resolution operations |
| 23 | +- `DIRegistry registry` - Custom DI container (~250 lines) for component wiring |
| 24 | +- `List<RemoteRepository> remoteRepositories` - Configured repositories |
| 25 | +- Configuration: `mavenSettings`, `mavenSettingsSecurity`, `repos`, `fresh`, `offline` |
| 26 | +- Flags: `mavenCentralEnabled`, `mavenApacheSnapshotEnabled` |
| 27 | +- `RepositoryResolver repositoryResolver` - Resolves repository IDs to URLs |
| 28 | + |
| 29 | +#### Key Methods |
| 30 | + |
| 31 | +**Lifecycle:** |
| 32 | +- `doBuild()` - Initialize all components (standalone mode) or use injected ones (embedded mode) |
| 33 | +- `doStop()` - Cleanup resources |
| 34 | + |
| 35 | +**Resolution:** |
| 36 | +- `resolveArtifacts(List<String> gavs, Set<String> extraRepos, boolean transitive, boolean useApacheSnapshots)` |
| 37 | +- `resolveAvailableVersions(String groupId, String artifactId, String repository)` |
| 38 | +- `customize(String localRepo, int connectTimeout, int requestTimeout)` - Create customized instance |
| 39 | + |
| 40 | +**Configuration:** |
| 41 | +- `setMavenSettingsLocation(String)`, `setMavenSettingsSecurityLocation(String)` |
| 42 | +- `setRepos(String)`, `setFresh(boolean)`, `setOffline(boolean)` |
| 43 | +- `setMavenCentralEnabled(boolean)`, `setMavenApacheSnapshotEnabled(boolean)` |
| 44 | +- `setRepositoryResolver(RepositoryResolver)` |
| 45 | + |
| 46 | +### Current Implementation Details |
| 47 | + |
| 48 | +#### Standalone Mode (lines 131-198) |
| 49 | +1. Create `DIRegistry` - custom DI container |
| 50 | +2. Call `validateMavenSettingsLocations()` - validate settings.xml paths |
| 51 | +3. Call `configureRepositorySystem()` - wire ~30 Maven Resolver components via DIRegistry |
| 52 | +4. Call `mavenConfiguration()` - read settings.xml, decrypt passwords, activate profiles |
| 53 | +5. Call `configureRepositorySystemSession()` - create session with local repo, proxies, mirrors |
| 54 | +6. Call `configureDefaultRepositories()` - build repository list from settings + custom repos |
| 55 | +7. Apply mirroring/proxying via `repositorySystem.newResolutionRepositories()` |
| 56 | + |
| 57 | +#### Embedded Mode (constructor with RepositorySystem + RepositorySystemSession) |
| 58 | +- Skip all DIRegistry setup |
| 59 | +- Use provided components directly |
| 60 | +- Still configure custom repositories if specified |
| 61 | + |
| 62 | +#### DIRegistry Configuration (~650 lines, lines 572-752) |
| 63 | +Manually wires these components: |
| 64 | +- `RepositorySystem`, `VersionResolver`, `ArtifactResolver`, `MetadataResolver` |
| 65 | +- `DependencyCollector`, `LocalRepositoryProvider`, `RemoteRepositoryManager` |
| 66 | +- HTTP/File transporters with connection pooling |
| 67 | +- Settings builder, decrypter, validator |
| 68 | +- Checksum policies, update policies, sync context |
| 69 | + |
| 70 | +This is the code MIMA eliminates! |
| 71 | + |
| 72 | +### Repository Configuration Logic |
| 73 | + |
| 74 | +**Default Repositories:** |
| 75 | +1. Maven Central (if enabled): `https://repo1.maven.org/maven2` |
| 76 | +2. Apache Snapshots (if enabled): `https://repository.apache.org/snapshots` |
| 77 | +3. Custom repos from `--repos` parameter (comma-separated URLs) |
| 78 | +4. Repositories from active profiles in settings.xml |
| 79 | + |
| 80 | +**Repository Policies:** |
| 81 | +- `POLICY_DEFAULT`: enabled, never update, warn on checksum failure |
| 82 | +- `POLICY_FRESH`: enabled, always update, warn on checksum failure |
| 83 | +- `POLICY_DISABLED`: disabled |
| 84 | + |
| 85 | +**Custom Repository Handling:** |
| 86 | +- Uses `RepositoryResolver` to resolve repository IDs to URLs |
| 87 | +- Skips Maven Central if already included |
| 88 | +- Detects Apache Snapshots and uses pre-configured instance |
| 89 | +- Assigns unique IDs to custom repos: "custom1", "custom2", etc. |
| 90 | + |
| 91 | +### Settings Processing |
| 92 | + |
| 93 | +**Settings Location Resolution:** |
| 94 | +- Explicit path via `setMavenSettingsLocation()` |
| 95 | +- `"false"` disables settings processing |
| 96 | +- Default: `~/.m2/settings.xml` if exists |
| 97 | +- Settings security: `~/.m2/settings-security.xml` if exists |
| 98 | + |
| 99 | +**Settings Features:** |
| 100 | +- Profile activation (activeByDefault) |
| 101 | +- Password decryption |
| 102 | +- Proxy configuration |
| 103 | +- Mirror configuration |
| 104 | +- Local repository location |
| 105 | + |
| 106 | +### Usage Patterns |
| 107 | + |
| 108 | +**Standalone (JBang, Kamelet Main):** |
| 109 | +```java |
| 110 | +MavenDownloaderImpl downloader = new MavenDownloaderImpl(); |
| 111 | +downloader.setMavenSettingsLocation(settingsPath); |
| 112 | +downloader.setRepos("https://custom.repo.com/maven2"); |
| 113 | +downloader.setFresh(true); |
| 114 | +downloader.build(); |
| 115 | +List<MavenArtifact> artifacts = downloader.resolveArtifacts( |
| 116 | + List.of("org.apache.camel:camel-core:4.0.0"), |
| 117 | + null, true, false); |
| 118 | +``` |
| 119 | + |
| 120 | +**Embedded (Maven Plugin):** |
| 121 | +```java |
| 122 | +MavenDownloaderImpl downloader = new MavenDownloaderImpl( |
| 123 | + repositorySystem, repositorySystemSession); |
| 124 | +downloader.build(); |
| 125 | +List<MavenArtifact> artifacts = downloader.resolveArtifacts(...); |
| 126 | +``` |
| 127 | + |
| 128 | +## MIMA Migration Strategy |
| 129 | + |
| 130 | +### What MIMA Provides |
| 131 | +- Automatic RepositorySystem creation (eliminates DIRegistry) |
| 132 | +- Automatic settings.xml processing (eliminates manual reading) |
| 133 | +- Automatic password decryption (eliminates manual decryption) |
| 134 | +- Dual runtime support: embedded-maven (in plugin) + standalone-static (outside) |
| 135 | +- ContextOverrides for customization (offline, fresh, settings paths) |
| 136 | + |
| 137 | +### What We Keep |
| 138 | +- Public API (all setter/getter methods) |
| 139 | +- Resolution methods (resolveArtifacts, resolveAvailableVersions) |
| 140 | +- Custom repository handling (repos parameter, RepositoryResolver) |
| 141 | +- Repository policies (fresh mode, enabled/disabled repos) |
| 142 | + |
| 143 | +### What We Remove |
| 144 | +- DIRegistry class and all component wiring (~650 lines) |
| 145 | +- Manual settings reading and decryption (~100 lines) |
| 146 | +- Manual RepositorySystemSession creation (~100 lines) |
| 147 | + |
| 148 | +### New Implementation Size |
| 149 | +Estimated: ~400 lines (down from 1,240 lines = 68% reduction) |
| 150 | + |
0 commit comments