diff --git a/.github/workflows/build-test-java.md b/.github/workflows/build-test-java.md
index eaabad46..006cb310 100644
--- a/.github/workflows/build-test-java.md
+++ b/.github/workflows/build-test-java.md
@@ -50,24 +50,7 @@ Clone and test the following projects from the test repository:
1. **Clone Repository**: `gh repo clone Mossaka/gh-aw-firewall-test-java /tmp/test-java`
- **CRITICAL**: If clone fails, immediately call `safeoutputs-missing_tool` with message "CLONE_FAILED: Unable to clone test repository" and stop execution
-2. **Configure Maven Proxy**: Maven ignores Java system properties for proxy configuration, so you must create `~/.m2/settings.xml` before running any Maven commands. **IMPORTANT**: Use the literal values `squid-proxy` and `3128` directly in the XML - do NOT use shell variables or environment variable syntax:
- ```bash
- mkdir -p ~/.m2
- cat > ~/.m2/settings.xml << 'SETTINGS'
-
-
-
- awf-httptruehttp
- squid-proxy3128
-
-
- awf-httpstruehttps
- squid-proxy3128
-
-
-
- SETTINGS
- ```
+2. **Maven Proxy**: Maven proxy configuration (`~/.m2/settings.xml`) is automatically generated by AWF's agent container entrypoint. No manual setup is needed.
3. **Test Projects**:
- `gson`: `cd /tmp/test-java/gson && mvn compile && mvn test`
diff --git a/containers/agent/entrypoint.sh b/containers/agent/entrypoint.sh
index 4f8170c8..609edba0 100644
--- a/containers/agent/entrypoint.sh
+++ b/containers/agent/entrypoint.sh
@@ -167,6 +167,39 @@ echo "[entrypoint] Proxy configuration:"
echo "[entrypoint] HTTP_PROXY=$HTTP_PROXY"
echo "[entrypoint] HTTPS_PROXY=$HTTPS_PROXY"
+# Generate Maven settings.xml with proxy configuration
+# Maven ignores JAVA_TOOL_OPTIONS and HTTP_PROXY; it requires ~/.m2/settings.xml
+if [ -n "$SQUID_PROXY_HOST" ] && [ -n "$SQUID_PROXY_PORT" ]; then
+ MAVEN_DIR="$(eval echo ~awfuser)/.m2"
+ if [ ! -f "$MAVEN_DIR/settings.xml" ]; then
+ mkdir -p "$MAVEN_DIR"
+ cat > "$MAVEN_DIR/settings.xml" << MAVEN_SETTINGS
+
+
+
+ awf-http
+ true
+ http
+ ${SQUID_PROXY_HOST}
+ ${SQUID_PROXY_PORT}
+
+
+ awf-https
+ true
+ https
+ ${SQUID_PROXY_HOST}
+ ${SQUID_PROXY_PORT}
+
+
+
+MAVEN_SETTINGS
+ chown awfuser:awfuser "$MAVEN_DIR" "$MAVEN_DIR/settings.xml"
+ echo "[entrypoint] ✓ Generated Maven settings.xml with proxy configuration"
+ else
+ echo "[entrypoint] Maven settings.xml already exists, skipping generation"
+ fi
+fi
+
# Print network information
echo "[entrypoint] Network information:"
echo "[entrypoint] IP address: $(hostname -I)"
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 93a8dd1d..862ceebb 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -161,39 +161,17 @@
AWF automatically sets `JAVA_TOOL_OPTIONS` with `-Dhttp.proxyHost`, `-Dhttp.proxyPort`, `-Dhttps.proxyHost`, `-Dhttps.proxyPort`, and `-Dhttp.nonProxyHosts` inside the agent container. This works for most Java tools that read standard JVM system properties, including Gradle and SBT.
-### Maven Requires Extra Configuration
+AWF also automatically generates `~/.m2/settings.xml` with proxy configuration in the agent container entrypoint. This ensures Maven builds work out of the box without manual configuration.
-**Problem:** Maven builds fail with network errors even though the domain is in `--allow-domains`
-
-**Cause:** Maven's HTTP transport (Apache HttpClient / Maven Resolver) ignores Java system properties for proxy configuration. Unlike Gradle and most other Java tools, Maven does **not** read `-DproxyHost`/`-DproxyPort` from `JAVA_TOOL_OPTIONS`.
-
-**Solution:** Create `~/.m2/settings.xml` with proxy configuration before running Maven:
-
-```bash
-mkdir -p ~/.m2
-cat > ~/.m2/settings.xml << EOF
-
-
-
- awf-httptruehttp
- ${SQUID_PROXY_HOST}${SQUID_PROXY_PORT}
-
-
- awf-httpstruehttps
- ${SQUID_PROXY_HOST}${SQUID_PROXY_PORT}
-
-
-
-EOF
-```
+### Gradle Works Automatically
-The `SQUID_PROXY_HOST` and `SQUID_PROXY_PORT` environment variables are automatically set by AWF in the agent container.
+Gradle reads JVM system properties via `ProxySelector.getDefault()`, so the `JAVA_TOOL_OPTIONS` environment variable set by AWF is sufficient. No extra configuration is needed for Gradle builds.
-For agentic workflows, add this as a setup step in the workflow `.md` file so the agent creates the file before running Maven commands.
+### Maven Works Automatically
-### Gradle Works Automatically
+Maven's HTTP transport (Apache HttpClient / Maven Resolver) ignores `JAVA_TOOL_OPTIONS` for proxy configuration. AWF handles this by automatically generating `~/.m2/settings.xml` with proxy settings in the agent container entrypoint. No manual configuration is needed.
-Gradle reads JVM system properties via `ProxySelector.getDefault()`, so the `JAVA_TOOL_OPTIONS` environment variable set by AWF is sufficient. No extra configuration is needed for Gradle builds.
+If you need to override the auto-generated `settings.xml` (e.g., to add custom repositories or mirrors), create your own `~/.m2/settings.xml` before running Maven — the entrypoint will not overwrite an existing file if one is bind-mounted.
### Why This Is Needed
@@ -201,7 +179,7 @@ AWF uses a forward proxy (Squid) for HTTPS egress control rather than transparen
- **Most tools**: Use `HTTP_PROXY`/`HTTPS_PROXY` environment variables (set automatically by AWF)
- **Java tools**: Use `JAVA_TOOL_OPTIONS` with JVM system properties (set automatically by AWF)
-- **Maven**: Requires `~/.m2/settings.xml` (must be configured manually — see above)
+- **Maven**: Uses `~/.m2/settings.xml` (generated automatically by AWF)
## Log Analysis
diff --git a/src/docker-manager.test.ts b/src/docker-manager.test.ts
index fad43378..71fcc2f5 100644
--- a/src/docker-manager.test.ts
+++ b/src/docker-manager.test.ts
@@ -494,6 +494,19 @@ describe('docker-manager', () => {
expect(env.SQUID_PROXY_PORT).toBe('3128');
});
+ it('should set JAVA_TOOL_OPTIONS with JVM proxy properties', () => {
+ const result = generateDockerCompose(mockConfig, mockNetworkConfig);
+ const agent = result.services.agent;
+ const env = agent.environment as Record;
+
+ expect(env.JAVA_TOOL_OPTIONS).toBeDefined();
+ expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttp.proxyHost=squid-proxy');
+ expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttp.proxyPort=3128');
+ expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttps.proxyHost=squid-proxy');
+ expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttps.proxyPort=3128');
+ expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttp.nonProxyHosts=localhost|127.0.0.1');
+ });
+
it('should mount required volumes in agent container (default behavior)', () => {
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
const agent = result.services.agent;
diff --git a/src/docker-manager.ts b/src/docker-manager.ts
index 299b4128..f42ed119 100644
--- a/src/docker-manager.ts
+++ b/src/docker-manager.ts
@@ -345,6 +345,10 @@ export function generateDockerCompose(
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
SQUID_PROXY_HOST: 'squid-proxy',
SQUID_PROXY_PORT: SQUID_PORT.toString(),
+ // JVM proxy configuration: Java ignores HTTP_PROXY/HTTPS_PROXY and requires
+ // system properties via JAVA_TOOL_OPTIONS. Works for Gradle, SBT, and most JVM tools.
+ // Maven requires separate ~/.m2/settings.xml (generated by entrypoint.sh).
+ JAVA_TOOL_OPTIONS: `-Dhttp.proxyHost=squid-proxy -Dhttp.proxyPort=${SQUID_PORT} -Dhttps.proxyHost=squid-proxy -Dhttps.proxyPort=${SQUID_PORT} -Dhttp.nonProxyHosts=localhost|127.0.0.1`,
HOME: homeDir,
PATH: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
// Configure one-shot-token library with sensitive tokens to protect