Ubuntu 22.04 安装 Apache Commons Net 指南

在 Ubuntu 22.04 上通过 APT 安装 OpenJDK 17 与 Maven,并以 Maven 依赖、官方二进制包两种方式集成 Apache Commons Net 3.13.0 的实测指南

Apache Commons NetApache Commons Net2026/10/15

Ubuntu 22.04 安装 Apache Commons Net 指南

目标:在 Ubuntu 22.04 服务器上完成 Apache Commons Net 3.13.0 的安装与最小验证,Maven 依赖与官方二进制包两种集成方式全部编译、运行成功。已在 Ubuntu 22.04.5 LTS(x86_64)+ OpenJDK 17.0.20.1 + Maven 3.6.3 实测通过。

一、环境信息

  • OS:Ubuntu 22.04.5 LTS(jammy)
  • 架构:x86_64
  • JDK:OpenJDK 17.0.20.1(APT 包 openjdk-17-jdk,17.0.20.1+1-1~22.04)
  • 构建工具:Apache Maven 3.6.3(APT 包 maven,3.6.3-5)
  • 组件版本:Apache Commons Net 3.13.0(2026-03-15 发布的官方最新稳定版)
  • Maven 坐标:commons-net:commons-net:3.13.0
  • 工作目录:/root/commons-net-demo(Maven 方案)、/root/jar-run(JAR 直跑方案)

二、前置条件

先刷新 APT 索引并安装 curl(用于网络连通性检查与下载二进制包):

apt-get update
apt-get install -y curl

输出节选(实测末尾):

Setting up curl (7.81.0-1ubuntu1.30) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...

检查两个关键下载源可达(官方下载站与 Maven 中央仓库):

curl -sI https://downloads.apache.org/commons/net/ | head -3
curl -sI https://repo1.maven.org/maven2/commons-net/commons-net/ | head -1

实测回显:

HTTP/1.1 200 OK
Date: Thu, 15 Oct 2026 01:14:27 GMT
Server: Apache
HTTP/2 200

两个源均返回 200,可继续。Commons Net 是一个纯 Java 的网络协议客户端工具集(FTP/SMTP/POP3/Telnet/NTP/TFTP 等客户端与子网计算工具),安装即"把 JAR 放进构建路径",不需要任何系统级服务。

三、版本选型说明

查看官方下载站的 binaries/ 目录,确认当前发布的稳定版:

curl -s https://downloads.apache.org/commons/net/binaries/ | grep -oE "commons-net-[0-9.]+[^\"< ]*" | sort -u

实测回显:

commons-net-3.13.0-bin.tar.gz
commons-net-3.13.0-bin.tar.gz.asc
commons-net-3.13.0-bin.tar.gz.sha512
commons-net-3.13.0-bin.zip
commons-net-3.13.0-bin.zip.asc
commons-net-3.13.0-bin.zip.sha512

官方站只保留最新版(3.13.0)。历史上各版本在 Maven 中央仓库的发布时间如下,供选型参考:

版本中央仓库发布时间
3.9.02022-11-26
3.10.02023-10-01
3.11.02024-05-29
3.11.12024-06-07
3.12.02025-07-28
3.13.02026-03-15

本文选 3.13.0:最新稳定版,修复了 vsftpd 中文环境列表解析、新增 SubnetUtils6 IPv6 子网支持等问题。

Java 基线用字节码版本实测验证——官方 JAR 的字节码 major version 为 52(即 Java 8),因此 JDK 8+ 均可运行,本文使用 Ubuntu 22.04 默认仓库中的 JDK 17:

javap -verbose -cp /root/commons-net-3.13.0/commons-net-3.13.0.jar org.apache.commons.net.ftp.FTPClient 2>/dev/null | grep -E "major|minor"

实测回显:

  minor version: 0
  major version: 52

还有一个选型要点必须知道:3.13.0 的 POM 声明了对 commons-io 的依赖,Maven 方案会自动带入;JAR 直跑方案在 FTP 传输场景需要手动补齐(实测缺失时报 NoClassDefFoundError,见方案 B 与 FAQ)。

💡 技术拓展:官方二进制包同时提供 .sha512 与 .asc 两种校验文件,用途不同:

校验方式校验内容依赖适用场景
.sha512文件完整性哈希无快速确认下载没有损坏或被截断
.ascGPG 签名本地导入 Apache 公钥审计发布者身份的强校验

本文日常安装用 .sha512(无需管理密钥环);安全审计场景建议叠加 .asc 验签。

四、方案 A:APT 安装 JDK/Maven + Maven 依赖集成(推荐)

4.1 安装 OpenJDK 17 与 Maven

apt-get install -y openjdk-17-jdk maven

输出节选(实测首尾):

The following NEW packages will be installed:
  adwaita-icon-theme alsa-topology-conf alsa-ucm-conf at-spi2-core
  ca-certificates-java dbus dbus-user-session dconf-gsettings-backend
  dconf-service default-jre-headless dmsetup fontconfig fontconfig-config
Setting up openjdk-17-jre-headless:amd64 (17.0.20.1+1-1~22.04) ...
Setting up maven (3.6.3-5) ...
Setting up openjdk-17-jdk:amd64 (17.0.20.1+1-1~22.04) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
Processing triggers for libgdk-pixbuf-2.0-0:amd64 (2.42.8+dfsg-1ubuntu0.5) ...

安装摘要行:0 upgraded, 222 newly installed, 0 to remove and 2 not upgraded.。

验证版本(APT 装完后 java、javac、mvn 均已在 PATH 中,无需配置 JAVA_HOME):

java -version
mvn -version | head -3

实测回显:

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
---
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64

4.2 创建最小验证工程

mkdir -p /root/commons-net-demo/src/main/java
cd /root/commons-net-demo

创建 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>demo</groupId>
  <artifactId>commons-net-demo</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>8</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>commons-net</groupId>
      <artifactId>commons-net</artifactId>
      <version>3.13.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.11.0</version>
      </plugin>
    </plugins>
  </build>
</project>

两个刻意为之的设置:maven.compiler.release=8 演示 Commons Net 3.13.0 的 Java 8 基线可以照常编译;显式固定 maven-compiler-plugin 3.11.0,避免老 Maven 内置插件版本过旧导致 release 参数被忽略(本文 Maven 3.6.3 实测必须固定后才稳定输出 release 8 编译日志)。

创建 src/main/java/SubnetDemo.java,用 SubnetUtils(不需要任何网络服务)做最小验证:

import org.apache.commons.net.util.SubnetUtils;
import org.apache.commons.net.util.SubnetUtils.SubnetInfo;

public class SubnetDemo {
    public static void main(String[] args) {
        SubnetUtils su = new SubnetUtils("192.168.56.0/26");
        SubnetInfo info = su.getInfo();
        System.out.println("[不含网络号/广播号] low=" + info.getLowAddress()
                + " high=" + info.getHighAddress()
                + " 可用地址数=" + info.getAddressCountLong());
        su.setInclusiveHostCount(true);
        info = su.getInfo();
        System.out.println("[含网络号/广播号]   low=" + info.getLowAddress()
                + " high=" + info.getHighAddress()
                + " 可用地址数=" + info.getAddressCountLong());
        System.out.println("network=" + info.getNetworkAddress()
                + " netmask=" + info.getNetmask()
                + " broadcast=" + info.getBroadcastAddress());
        System.out.println("isInRange(192.168.56.100) = " + info.isInRange("192.168.56.100"));
        System.out.println("isInRange(192.168.57.100) = " + info.isInRange("192.168.57.100"));
        System.out.println("commons-net OK");
    }
}

4.3 编译、依赖分析与运行

cd /root/commons-net-demo
mvn -B compile

输出节选(实测):

[INFO] Building commons-net-demo 1.0.0
[INFO] Compiling 1 source file with javac [debug release 8] to target/classes
[INFO] BUILD SUCCESS
[INFO] Total time:  02:09 min
[INFO] Finished at: 2026-10-15T01:16:48Z

用 dependency:tree 确认依赖关系,能看到 3.13.0 传递依赖的 commons-io 版本:

mvn -q dependency:tree -DoutputFile=deptree.txt
cat deptree.txt

实测回显:

demo:commons-net-demo:jar:1.0.0
\- commons-net:commons-net:jar:3.13.0:compile
   \- commons-io:commons-io:jar:2.21.0:compile

运行验证程序:

java -Dfile.encoding=UTF-8 -cp target/classes:$HOME/.m2/repository/commons-net/commons-net/3.13.0/commons-net-3.13.0.jar:$HOME/.m2/repository/commons-io/commons-io/2.21.0/commons-io-2.21.0.jar SubnetDemo

实测回显:

[不含网络号/广播号] low=192.168.56.1 high=192.168.56.62 可用地址数=62
[含网络号/广播号]   low=192.168.56.0 high=192.168.56.63 可用地址数=64
network=192.168.56.0 netmask=255.255.255.192 broadcast=192.168.56.63
isInRange(192.168.56.100) = false
isInRange(192.168.57.100) = false
commons-net OK

验证结果:/26 网段解析出 62 个可用地址(不含网络号与广播号)或 64 个(含),192.168.56.100 落在 64~127 段所以判定不在 /26 范围内,全部符合预期,安装完成。

要点提示:日常开发只需要把 commons-net:commons-net:3.13.0 写进自己的 POM,commons-io 会由 Maven 自动带入,手工把两个 JAR 拼进 -cp 只是本节验证手段。

五、方案 B:官方二进制包手动集成(不使用 Maven)

适合没有 Maven 的机器、内网无法访问中央仓库,或只想快速验证一个脚本的场景。

5.1 下载与校验

cd /root
curl -O https://downloads.apache.org/commons/net/binaries/commons-net-3.13.0-bin.tar.gz
curl -O https://downloads.apache.org/commons/net/binaries/commons-net-3.13.0-bin.tar.gz.sha512
ls -l commons-net-3.13.0-bin.tar.gz
echo "期望: $(cut -d " " -f1 commons-net-3.13.0-bin.tar.gz.sha512)"
echo "实测: $(sha512sum commons-net-3.13.0-bin.tar.gz | cut -d " " -f1)"

实测回显(期望与实测哈希一致):

-rw-r--r-- 1 root root 2352355 Oct 15 01:19 commons-net-3.13.0-bin.tar.gz
期望: 4827d6ea3cfcfba317dfac35c0ca013b737935253639302c274ebf2adeaa4d2fa36ccc36f92be32f76dd25c8bef72a116b308ca3e823b50af1b843f389c30b6f
实测: 4827d6ea3cfcfba317dfac35c0ca013b737935253639302c274ebf2adeaa4d2fa36ccc36f92be32f76dd25c8bef72a116b308ca3e823b50af1b843f389c30b6f

解压并查看包内容:

tar xzf commons-net-3.13.0-bin.tar.gz
ls commons-net-3.13.0/
ls -l commons-net-3.13.0/commons-net-3.13.0.jar

实测回显:

LICENSE.txt
NOTICE.txt
README.md
RELEASE-NOTES.txt
apidocs
commons-net-3.13.0-sources.jar
commons-net-3.13.0.jar
commons-net-examples-3.13.0.jar
org
-rw-r--r-- 1 root root 337311 Mar 15  2026 commons-net-3.13.0/commons-net-3.13.0.jar

5.2 编译与运行

mkdir -p /root/jar-run && cd /root/jar-run
cp /root/commons-net-3.13.0/commons-net-3.13.0.jar .
cp /root/commons-net-demo/src/main/java/SubnetDemo.java .
javac -encoding UTF-8 -cp commons-net-3.13.0.jar -d out SubnetDemo.java
java -Dfile.encoding=UTF-8 -cp out:commons-net-3.13.0.jar SubnetDemo

实测回显:

[不含网络号/广播号] low=192.168.56.1 high=192.168.56.62 可用地址数=62
[含网络号/广播号]   low=192.168.56.0 high=192.168.56.63 可用地址数=64
network=192.168.56.0 netmask=255.255.255.192 broadcast=192.168.56.63
isInRange(192.168.56.100) = false
isInRange(192.168.57.100) = false
commons-net OK

验证结果:与方案 A 完全一致,javac -cp 与 java -cp 均直接工作。要点提示:SubnetUtils 这类纯工具类不触碰 commons-io,上面只挂一个 JAR 就能跑;但 FTP 文件传输路径实测会加载 org.apache.commons.io.output.ProxyOutputStream 等类,届时必须把 commons-io-2.21.0.jar(可从中央仓库下载同一坐标)一并加入 classpath,否则抛 NoClassDefFoundError(本系列《快速入门与集成示例》中有该报错的完整实测记录)。

六、方案对比与选择建议

维度方案 A:Maven 依赖方案 B:官方 bin 包直跑
版本升级改 POM 版本号即可重新下载、校验、解压
传递依赖自动带入 commons-io需手工补齐,容易漏
离线/内网需私服或提前拉取只需一个 tar 包
工程化标准构建、可进 CI适合临时脚本与排障
本文结论首选辅助、救急

选择建议:所有正式工程一律走方案 A;方案 B 留给无法访问中央仓库的边缘节点,以及需要对照官方原版 JAR 排查依赖冲突的场景。

七、配置说明

  • Commons Net 本身没有配置文件,所有行为都通过运行时 API 设置(超时、字符集、传输模式等),详见本系列《配置参数详解》。
  • JVM 层面建议显式指定编码,避免控制台中文乱码:java -Dfile.encoding=UTF-8(本文所有运行命令均带该参数)。
  • Maven 本地仓库位于 /root/.m2/repository,Commons Net 安装后落在 /root/.m2/repository/commons-net/commons-net/3.13.0/,排查版本冲突时直接看这个目录。
  • 如果服务器需要经代理访问中央仓库,在 mvn 命令行追加 -Dhttps.proxyHost=<代理地址> -Dhttps.proxyPort=<端口>;Commons Net 自身发起的 FTP/SMTP 连接不受该参数影响。

八、多版本管理

多个 Commons Net 版本可以在本地仓库中并列共存,切换时改 POM 即可。实测拉取一个旧版本:

mvn -q dependency:get -Dartifact=commons-net:commons-net:3.11.1
ls -1 $HOME/.m2/repository/commons-net/commons-net/

实测回显:

3.11.1
3.13.0

两个版本目录并存,dependency:tree 中当前工程解析到哪个版本一目了然:

mvn dependency:tree | grep commons-net

实测回显:

\- commons-net:commons-net:jar:3.13.0:compile

要点提示:同一工程内不要同时直接引入两个版本的 Commons Net,Maven 就近原则只会保留一个,另一个的类若被别的库引用会直接 ClassNotFoundException。

九、常见问题(FAQ)

  1. 运行 FTP 示例报 NoClassDefFoundError: org/apache/commons/io/output/ProxyOutputStream?3.13.0 把文件传输的流包装实现迁移到了 commons-io,Maven 方案自动带入 2.21.0;JAR 直跑方案要手动把它加入 classpath。SubnetUtils 等纯工具类不受影响。
  2. javac 报 release version 8 not supported?说明实际在用 JDK 7 或更老版本。Commons Net 3.13.0 字节码基线是 Java 8(major version 52,实测见第三节),装 openjdk-17-jdk 即可覆盖。
  3. Maven 编译没有按 maven.compiler.release=8 执行?Ubuntu 22.04 的 Maven 3.6.3 默认绑定的 compiler 插件版本偏旧,按第四节 POM 显式固定 maven-compiler-plugin 3.11.0 后,编译日志会明确出现 javac [debug release 8]。
  4. 控制台中文乱码?给 java 加 -Dfile.encoding=UTF-8;FTP 控制通道与服务端交互的编码由 FTPClient 自己的参数控制,与 JVM 编码是两回事,详见《配置参数详解》。
  5. 中央仓库下载慢或超时?可改用国内镜像,或按第七节用代理参数;完全离线则走方案 B。

十、卸载与清理

先预览要移除的系统包(-s 模拟模式,不会真的卸载):

apt-get -s purge -y openjdk-17-jdk maven 2>/dev/null | grep -E "The following packages will be REMOVED|^  maven|Purg"

实测回显:

The following packages will be REMOVED:
  maven* openjdk-17-jdk*
Purg maven [3.6.3-5]
Purg openjdk-17-jdk [17.0.20.1+1-1~22.04]

确认无误后去掉 -s 执行真卸载,并清理依赖与工程文件:

apt-get purge -y openjdk-17-jdk maven
apt-get autoremove -y
rm -rf /root/commons-net-demo /root/jar-run
rm -rf /root/commons-net-3.13.0 /root/commons-net-3.13.0-bin.tar.gz /root/commons-net-3.13.0-bin.tar.gz.sha512
rm -rf /root/.m2/repository/commons-net

最后一条只删 Commons Net 的本地仓库缓存,~/.m2 其余内容保留;若要彻底回到初始状态,直接 rm -rf /root/.m2。

十一、参考链接