platform/testFramework/selfContainedProjects/README.md
A caching HTTP proxy that enables truly offline Gradle builds by pre-warming an artifact cache.
CachingHttpProxy.kt - HTTP proxy server that caches Maven repository requestsinit.gradle.kts - Gradle init script that routes all repository URLs through the proxyval proxy = CachingHttpProxy(
listen = InetSocketAddress("127.0.0.1", 8080),
cacheDir = Path.of("/path/to/cache"),
offline = false // Start in online mode
)
println("Proxy URL: ${proxy.proxyUrl}")
// Output: http://127.0.0.1:8080/proxy
export SELF_CONTAINED_PROXY_URL="http://127.0.0.1:8080/proxy"
export SELF_CONTAINED_VERBOSE="true" # Optional
Note: URL must NOT end with a trailing slash.
gradle --init-script /path/to/init.gradle.kts build
This downloads and caches all artifacts through the proxy.
proxy.offline = true
Now Gradle builds work completely offline using only the cache.
Cache Warming (Online Mode):
Offline Mode:
cache/
├── repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0/
│ ├── kotlin-stdlib-1.9.0.jar
│ ├── kotlin-stdlib-1.9.0.jar.headers
│ ├── kotlin-stdlib-1.9.0.pom
│ └── kotlin-stdlib-1.9.0.pom.headers
└── plugins.gradle.org/m2/...
Each artifact has:
.jar, .pom, etc.).headers) with HTTP status and headers# Setup (once)
./gradlew --init-script init.gradle.kts build
tar -czf gradle-cache.tar.gz /path/to/cache
# Each build
tar -xzf gradle-cache.tar.gz
# Start proxy in offline mode
./gradlew --init-script init.gradle.kts build
export SELF_CONTAINED_PROXY_URL="http://127.0.0.1:8080/proxy"
Remove trailing slash from the URL.
Switch to online mode and re-run build to cache the missing artifact.
Verify init script is applied:
gradle --init-script /path/to/init.gradle.kts build --info | grep SELF-CONTAINED
Use port 0 for automatic port selection:
val proxy = CachingHttpProxy(
listen = InetSocketAddress("127.0.0.1", 0),
// ...
)
println("Port: ${proxy.port}")
| Variable | Required | Description |
|---|---|---|
SELF_CONTAINED_PROXY_URL | Yes | Proxy base URL (no trailing slash) |
SELF_CONTAINED_VERBOSE | No | Enable verbose logging (default: true) |