Ubuntu Java编译时网络问题的排查与解决
一 先快速定位问题归属
- 判断是系统网络不通还是 Java 构建工具(如 Maven/Gradle)访问外网受限:
- 系统层面:ping 一个可达域名与 IP
- ping -c 4 8.8.8.8
- ping -c 4 www.google.com
- DNS 解析:nslookup www.google.com
- 端口连通:nc -vz repo.maven.apache.org 443 或 telnet repo.maven.apache.org 443
- 本机监听与路由:ss -ltnp | grep :8080;ip route
- 防火墙状态:sudo ufw status(必要时临时放行:sudo ufw allow out 80,443/tcp)
- 若你使用 VMware/VirtualBox,确认网络适配器为 NAT/桥接 并能获取地址
- 若只看到 lo 接口或图标无网络,多为 NetworkManager 异常,可尝试:sudo systemctl restart NetworkManager;必要时检查 /etc/NetworkManager/NetworkManager.conf 的 managed 配置并清理状态后重启
二 常见场景与对应处理
- 公司或校园网需要 HTTP/HTTPS 代理
- 构建工具传参(推荐作用于构建过程)
- Maven:在 settings.xml 的 配置,或在命令行加 -Dhttp.proxyHost=… -Dhttps.proxyPort=…
- Gradle:在 gradle.properties 中设置 systemProp.http.proxyHost / systemProp.https.proxyPort
- 全局环境变量(影响所有 Java 进程)
- export http_proxy=http://user:pass@host:port
- export https_proxy=http://user:pass@host:port
- 如代理不需认证可省略 user:pass;对 localhost/127.0.0.1 不走代理可设置 no_proxy=localhost,127.0.0.1
- Java 代码或测试内发起 HTTP 请求时,亦可在代码中设置:
- System.setProperty(“http.proxyHost”,“proxy.example.com”); System.setProperty(“http.proxyPort”,“8080”);
- 需要认证时再加:System.setProperty(“http.proxyUser”,“u”); System.setProperty(“http.proxyPassword”,“p”)
- 构建需要下载依赖但 DNS 解析慢或失败
- 临时更换 DNS:echo “nameserver 8.8.8.8” | sudo tee /etc/resolv.conf
- 使用 netplan 的系统(Ubuntu 18.04+ 常见):编辑 /etc/netplan/*.yaml,在 nameservers.addresses 中加入 8.8.8.8/8.8.4.4,然后 sudo netplan apply
- 防火墙/安全组拦截
- 放行外联 80/443:sudo ufw allow out 80/tcp;sudo ufw allow out 443/tcp
- 云服务器检查 安全组 是否允许出站 80/443
- 虚拟机网络模式不当
- 在 VMware/VirtualBox 中切换 NAT/桥接 后重启虚拟机,确保能拿到地址并上网
三 构建工具与常见异常的针对性建议
- 针对性建议
- 使用国内镜像加速(示例为 Maven,Gradle 可在 repositories 中使用相同镜像)
-
aliyunmaven
central
Aliyun Maven
https://maven.aliyun.com/repository/central
- 增大连接/读取超时(Maven:在 settings.xml 的 或 / 中配置 ;Gradle:在 build.gradle 的 repositories 或任务级配置 systemProp.http.socketTimeout / https.socketTimeout)
- 并行拉取与失败重试(Maven:-T 1C,必要时增加 -U 强制更新;Gradle:org.gradle.parallel=true,并配置重试策略)
- 常见异常与处理要点
- java.net.UnknownHostException:DNS 问题,检查 /etc/resolv.conf、nslookup,或临时改用 8.8.8.8
- java.net.ConnectException / SocketTimeoutException:目标主机不可达或端口不通,先用 nc/telnet 验证 443,再查防火墙/代理
- javax.net.ssl.SSLHandshakeException:证书不受信任或协议不匹配,导入根证书到 JDK cacerts,或在测试环境临时调低校验(不建议生产)
- java.net.BindException:端口被占用,换端口或结束占用进程(ss -ltnp | grep :端口)
四 一键自检与修复脚本
- 将以下脚本保存为 check_java_net.sh,chmod +x 后执行,可快速定位与修复常见问题
#!/usr/bin/env bash
set -Eeuo pipefail
echo "=== 1) 接口与路由 ==="
ip addr || true
ip route || true
echo "=== 2) 基本连通性 ==="
ping -c 4 8.8.8.8 || echo "[WARN] ICMP 被禁或网络不通"
nslookup www.google.com || echo "[WARN] DNS 解析失败"
echo "=== 3) 代理环境变量 ==="
env | grep -i -E '^(HTTP_|HTTPS_|NO_)?PROXY'
echo "=== 4) 防火墙状态 ==="
sudo ufw status || true
echo "=== 5) 测试 Maven Central 443 ==="
nc -vz repo.maven.apache.org 443 || echo "[WARN] 443 端口不通,检查代理/防火墙"
echo "=== 6) 可选:重启 NetworkManager ==="
sudo systemctl restart NetworkManager && echo "[INFO] NetworkManager 已重启" || echo "[WARN] 重启失败或无此服务"
echo "=== 7) 可选:写入公共 DNS ==="
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf >/dev/null
echo "nameserver 8.8.4.4" | sudo tee -a /etc/resolv.conf >/dev/null
echo "[INFO] 已写入 8.8.8.8/8.8.4.4 到 /etc/resolv.conf(可能被系统服务覆盖)"
- 若你使用 netplan,在确认 DNS 写入后仍无效,请编辑 /etc/netplan/*.yaml 增加 nameservers 后执行 sudo netplan apply