Ubuntu 22.04 安装 Apache Commons Email 指南
在 Ubuntu 22.04 从零搭建 Apache Commons Email 使用环境:安装 JDK 17 与 Maven,给出 Maven 依赖与官方发行包两种 jar 获取方案,含 sha512 校验、最小发信验证与卸载。
Ubuntu 22.04 安装 Apache Commons Email 指南
目标:在一台全新的 Ubuntu 22.04 服务器上搭建可编译、可运行 Apache Commons Email 的 Java 环境,并用两种方式获取 jar(Maven 依赖、官方发行包手动安装),最后完成最小发信验证。全部命令与回显已在 Ubuntu 22.04(JDK 17 + Maven)实测通过。
一、环境信息
本章先确认操作系统版本,再安装 JDK 17 与 Maven,为后续获取 Commons Email 做准备。Commons Email 1.6.0 的字节码目标是 Java 8(jar 内清单 Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"),因此 JDK 8 及以上均可运行,本文统一使用 JDK 17 作为开发与运行环境。
先确认系统版本:
cat /etc/os-release | grep -E "^(NAME|VERSION)="
实测回显:
NAME="Ubuntu"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
安装 JDK 17 与 Maven(约 1~2 分钟,取决于网络):
sudo apt update
sudo apt install -y openjdk-17-jdk maven
实测回显(节选,实测首尾):
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
maven is already the newest version (3.6.3-5).
openjdk-17-jdk is already the newest version (17.0.20.1+1-1~22.04).
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
already the newest version 表示本机已装好这两个包;在全新机器上首次执行会进入下载与 Setting up 阶段。验证安装结果:
java -version
javac -version
mvn -v
实测回显:
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)
javac 17.0.20.1
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
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"
输出中 Java version: 17.0.20.1 说明 Maven 已经用上了刚安装的 JDK 17。若这一行显示的是其他版本,请在 ~/.bashrc 中追加 export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 后重新登录。
💡 技术拓展:在动手装库之前,先分清「邮件协议」和「Java 邮件库」两个层面。协议是客户端与邮件服务器之间、以及服务器之间收发信的标准(SMTP/SMTPS/IMAP/POP3);库是帮你按这些协议对话的编程接口。常见协议与 Java 库的对比如下:
| 名称 | 归属 | 作用 | 典型端口 |
|---|---|---|---|
| SMTP | 协议 | 客户端把邮件交给发信服务器 | 25(明文)、587(提交) |
| SMTPS | 协议 | 从连接起就用 TLS 加密的 SMTP | 465 |
| STARTTLS | 协议扩展 | 明文连接上协商升级为加密 | 25/587 |
| IMAP | 协议 | 客户端从服务器读取/保持邮件 | 143(明文)、993(TLS) |
| POP3 | 协议 | 客户端从服务器下载邮件 | 110(明文)、995(TLS) |
| JavaMail(jakarta.mail) | 库 | 协议底层实现,Commons Email 的依赖 | 不直接暴露 |
| Commons Email | 库 | 在 JavaMail 之上封装发信 API | 不直接暴露 |
| Spring Mail | 库 | Spring 体系封装,底层同样用 JavaMail | 不直接暴露 |
Commons Email 本身只封装发信方向(SimpleEmail/HtmlEmail 等),底层依赖 JavaMail(com.sun.mail:jakarta.mail)完成 SMTP/SMTPS 会话;读信方向需要直接用 JavaMail 的 IMAP/POP3 API。本文统一使用 Commons Email 1.6.0。
二、版本选型
Commons Email 的稳定版只挂在官方归档站,主下载目录 downloads.apache.org 现仅提供 2.0.0 里程碑预览版。下表列出常用版本(JDK 要求以各版本 jar 清单与官方发布说明为准):
| 版本 | 发布状态 | 命名空间与依赖 | JDK 要求 | 适用场景 |
|---|---|---|---|---|
| 1.6.0 | 最新稳定版(2023-12) | javax.mail(传递依赖 jakarta.mail 1.6.7 + jakarta.activation 1.2.1) | Java 8 及以上 | 新项目首选 |
| 1.5.0 | 稳定版 | javax.mail(传递依赖 javax.mail 1.5.6) | Java 6 及以上 | 需回退旧 API 时 |
| 2.0.0-M1 | 里程碑预览版 | jakarta.mail(Jakarta EE 10 命名空间,artifactId 为 commons-email2) | Java 8 及以上 | 预研 Jakarta 迁移 |
关于「JDK 要求」的实测依据:1.6.0 的 jar 清单含 Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"、Build-Jdk-Spec: 21;1.5.0 的清单为 (&(osgi.ee=JavaSE)(version=1.6))、Build-Jdk: 1.8.0_131。
本文统一采用以下坐标与下载地址(均实测有效):
Maven 坐标:org.apache.commons:commons-email:1.6.0
发行包:https://archive.apache.org/dist/commons/email/binaries/commons-email-1.6.0-bin.tar.gz
校验文件:https://archive.apache.org/dist/commons/email/binaries/commons-email-1.6.0-bin.tar.gz.sha512
sha512(实测):
6a4a10caf0b34f03a11ff304d5f6f375f9db4b308d90faae3e6481e65aa7a656878f75f125fffbf810cb6f593be7421f28ee28fe3186235ff8e0ea314ec4a20c
两点实测结论需要提前知道:
- 发行包仅 1,257,491 字节,解压后只有主 jar 与 sources/tests/javadoc jar,没有
lib/目录,必需依赖要自行下载。这与一些大体积发行包(把依赖一并打包)不同。 - 1.6.0 的依赖坐标虽叫
jakarta.mail,但 jar 清单里Import-Package: javax.activation,javax.mail,...,代码里也仍用javax.mail包名(实测缺依赖时报NoClassDefFoundError: javax/mail/MessagingException)。这是 JavaMail 1.6 的历史命名,不是 Jakarta EE 10 的jakarta.mail。
💡 技术拓展:Java 生态里能发邮件的库不止一家,选库前可参考下表,本文的主角是封装度最高的 Commons Email:
| 库 | 坐标 | 发信 API 复杂度 | 读信能力 | 特点 |
|---|---|---|---|---|
| JavaMail(jakarta.mail) | com.sun.mail:jakarta.mail | 高(需自己组装 MimeMessage/Session) | 有(IMAP/POP3) | 底层实现,Commons Email 的依赖 |
| Commons Email | org.apache.commons:commons-email | 低(SimpleEmail 一行发信) | 无 | 面向发信的便捷封装 |
| Spring Mail | org.springframework:spring-context-support | 中(JavaMailSender 接口) | 无 | 适合已在用 Spring 的工程 |
三、方案A:Maven 中央仓库依赖
方案A通过 Maven 自动下载 jar 及其全部传递依赖,是工程化项目的推荐做法。先创建项目骨架:
mkdir -p /opt/mail-demo/src/main/java/net/quzuo/demo
cd /opt/mail-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>net.quzuo.demo</groupId>
<artifactId>mail-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.6.0</version>
</dependency>
</dependencies>
</project>
逐项说明:maven.compiler.source/target 指定按 Java 17 语法编译;project.build.sourceEncoding 强制源码按 UTF-8 读取;dependencies 只声明了 commons-email 一个依赖,JavaMail 与 activation 会作为传递依赖自动引入。验证依赖解析结果:
mvn dependency:tree
实测回显(节选,实测首尾):
[INFO] net.quzuo.demo:mail-demo:jar:1.0.0
[INFO] \- org.apache.commons:commons-email:jar:1.6.0:compile
[INFO] \- com.sun.mail:jakarta.mail:jar:1.6.7:compile
[INFO] \- com.sun.activation:jakarta.activation:jar:1.2.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
可以看到 jakarta.mail、jakarta.activation 两个 jar 都是 compile 作用域,即编译和运行都需要;它们就是 1.6.0 的全部传递依赖。写入最小验证程序 src/main/java/net/quzuo/demo/HelloEmail.java:
package net.quzuo.demo;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.SimpleEmail;
public class HelloEmail {
public static void main(String[] args) throws Exception {
Email email = new SimpleEmail();
email.setHostName("127.0.0.1");
email.setSmtpPort(25);
email.setCharset("UTF-8");
email.setFrom("sender@quzuo.net");
email.setSubject("Commons Email minimal test");
email.setMsg("hello commons email, sent from Ubuntu 22.04");
email.addTo("receiver@quzuo.net");
String messageId = email.send();
System.out.println("邮件已发送, Message-ID: " + messageId);
System.out.println("commons-email 版本: " + Email.class.getPackage().getImplementationVersion());
System.out.println("验证通过");
}
}
程序逻辑:SimpleEmail 是最简纯文本邮件类;依次设置发信服务器地址、端口、字符集、发件人、主题、正文、收件人,调用 send() 后返回邮件服务器分配的 Message-ID;最后从 jar 清单打印库版本。编译运行:
mvn -q compile exec:java -Dexec.mainClass=net.quzuo.demo.HelloEmail
说明:exec:java 来自 exec-maven-plugin,首次使用 Maven 会自动下载该插件(本次实测直接可用,无需在 pom 里显式声明)。实测回显:
邮件已发送, Message-ID: <1618212626.0.1791909073932@localhost>
commons-email 版本: 1.6.0
验证通过
三行输出分别确认了「发信链路连通」「jar 版本」「程序正常退出」。方案A安装完成。
四、方案B:官方发行包手动安装
方案B适合无法使用 Maven 的机器:从官方归档站下载发行包,手动拼类路径编译运行。创建安装目录并下载:
sudo mkdir -p /opt/mail
cd /opt/mail
sudo curl -fsSLO https://archive.apache.org/dist/commons/email/binaries/commons-email-1.6.0-bin.tar.gz
sudo curl -fsSLO https://archive.apache.org/dist/commons/email/binaries/commons-email-1.6.0-bin.tar.gz.sha512
ls -l
实测回显:
total 1264
-rw-r--r-- 1 root root 1257491 Oct 13 16:32 commons-email-1.6.0-bin.tar.gz
-rw-r--r-- 1 root root 129 Oct 13 16:32 commons-email-1.6.0-bin.tar.gz.sha512
发行包 1,257,491 字节。.sha512 文件内容为裸哈希(129 字节:128 个十六进制字符加换行),校验时要把它拼成 哈希 文件名 的标准格式再交给 sha512sum -c:
printf '%s %s\n' "$(cat commons-email-1.6.0-bin.tar.gz.sha512)" commons-email-1.6.0-bin.tar.gz | sha512sum -c -
实测回显:
commons-email-1.6.0-bin.tar.gz: OK
校验通过后解压并查看包内容:
sudo tar xzf commons-email-1.6.0-bin.tar.gz
ls commons-email-1.6.0/
实测回显:
LICENSE.txt NOTICE.txt RELEASE-NOTES.txt apidocs
commons-email-1.6.0-javadoc.jar
commons-email-1.6.0-sources.jar
commons-email-1.6.0-test-sources.jar
commons-email-1.6.0-tests.jar
commons-email-1.6.0.jar
关键点:发行包里只有主 jar 与源码/测试/javadoc jar,没有 lib/ 目录,必需依赖需要自行下载。下载两个必需依赖 jar 到解压目录旁的 lib/:
cd /opt/mail/commons-email-1.6.0
sudo mkdir -p lib
cd lib
sudo curl -fsSLO https://repo1.maven.org/maven2/com/sun/mail/jakarta.mail/1.6.7/jakarta.mail-1.6.7.jar
sudo curl -fsSLO https://repo1.maven.org/maven2/com/sun/activation/jakarta.activation/1.2.1/jakarta.activation-1.2.1.jar
ls -l
实测回显:
total 740
-rw-r--r-- 1 root root 65690 Oct 13 16:32 jakarta.activation-1.2.1.jar
-rw-r--r-- 1 root root 676654 Oct 13 16:32 jakarta.mail-1.6.7.jar
写入与方案A相同的验证程序(去掉 package net.quzuo.demo; 首行后保存为 /opt/mail/HelloEmail.java)。先演示一个必踩的坑——发行包 jar 没声明 Main-Class,直接 java -jar 会失败:
cd /opt/mail
java -jar commons-email-1.6.0/commons-email-1.6.0.jar
echo "退出码: $?"
实测回显:
no main manifest attribute, in commons-email-1.6.0/commons-email-1.6.0.jar
退出码: 1
原因:Commons Email 是纯库,jar 清单里根本没有 Main-Class,不能当命令行工具直接运行。正确的运行形态是 -cp 列出主 jar 与依赖 jar、再指定自己的主类。先看缺依赖时的报错,确认依赖是必需项:
java -Dfile.encoding=UTF-8 -cp "commons-email-1.6.0/commons-email-1.6.0.jar" HelloEmail.java
实测回显(节选,实测首尾):
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/MessagingException
at HelloEmail.main(HelloEmail.java:6)
Caused by: java.lang.ClassNotFoundException: javax.mail.MessagingException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
(HelloEmail.java 会被 Java 11+ 的源码启动模式直接编译执行,因此这里能触发依赖缺失;报错里的 javax.mail 也再次印证了 1.6.0 用的是 javax 命名空间。)补上依赖后编译并运行:
cd /opt/mail
javac -encoding UTF-8 -cp "commons-email-1.6.0/commons-email-1.6.0.jar:commons-email-1.6.0/lib/*" HelloEmail.java
java -Dfile.encoding=UTF-8 -cp ".:commons-email-1.6.0/commons-email-1.6.0.jar:commons-email-1.6.0/lib/*" HelloEmail
实测回显:
邮件已发送, Message-ID: <1254526270.0.1791909232371@localhost>
commons-email 版本: 1.6.0
验证通过
注意 Linux 类路径分隔符是冒号 :(Windows 是分号),lib/* 中的星号由 JVM 自己展开。方案B安装完成。
五、方案对比与选型建议
| 对比项 | 方案A:Maven 依赖 | 方案B:发行包手动安装 |
|---|---|---|
| 依赖管理 | 自动引入 2 个传递依赖 | 手动逐个下载,漏一个就运行报错 |
| 升级成本 | 改一行版本号重新构建 | 重新下载、校验、解压、改脚本 |
| 离线部署 | 需内网私服或预下载 | 天然离线友好 |
| 可复现性 | pom 锁版本,强 | 依赖脚本与人为记录 |
| 适用场景 | 一切有构建工具的工程 | 无 Maven 的跳板机、快速验证、交付现场 |
选型建议:开发/CI 环境一律方案A;目标机器没有 Maven 或需要临时排查时用方案B;方案B的两个依赖 jar 也建议从中央仓库按 pom 里实测的版本号下载,避免混用其他版本。
六、多版本管理
同一台机器上共存多个 Commons Email 版本,推荐用「版本目录 + current 符号链接」的方式管理:所有版本平铺在 /opt/mail/versions/ 下,current 指向当前生效版本,切换时只改链接。1.6.0 与 1.5.0 各建一个版本目录(1.5.0 的主 jar 名为 commons-email-1.5.jar,依赖为 javax.mail 1.5.6,从中央仓库按其版本下载):
cd /opt/mail
sudo mkdir -p versions/commons-email-1.6.0/lib versions/commons-email-1.5.0/lib
sudo cp commons-email-1.6.0/commons-email-1.6.0.jar versions/commons-email-1.6.0/lib/
sudo cp commons-email-1.6.0/lib/*.jar versions/commons-email-1.6.0/lib/
sudo curl -fsSL -o versions/commons-email-1.5.0/lib/commons-email-1.5.jar https://repo1.maven.org/maven2/org/apache/commons/commons-email/1.5/commons-email-1.5.jar
sudo curl -fsSL -o versions/commons-email-1.5.0/lib/javax.mail-1.5.6.jar https://repo1.maven.org/maven2/com/sun/mail/javax.mail/1.5.6/javax.mail-1.5.6.jar
sudo curl -fsSL -o versions/commons-email-1.5.0/lib/jakarta.activation-1.2.1.jar https://repo1.maven.org/maven2/com/sun/activation/jakarta.activation/1.2.1/jakarta.activation-1.2.1.jar
sudo ln -sfn commons-email-1.6.0 versions/current
ls -l versions/
实测回显(节选):
drwxr-xr-x 3 root root 4096 Oct 13 16:34 commons-email-1.5.0
drwxr-xr-x 3 root root 4096 Oct 13 16:34 commons-email-1.6.0
lrwxrwxrwx 1 root root 19 Oct 13 16:35 current -> commons-email-1.6.0
用 current 链接运行一次验证程序(复用第四章的 HelloEmail.java,放到 /opt/mail/):
cd /opt/mail
java -Dfile.encoding=UTF-8 -cp ".:versions/current/commons-email-1.6.0.jar:versions/current/lib/*" HelloEmail
实测回显:
邮件已发送, Message-ID: <662441761.0.1791910531751@localhost>
commons-email 版本: 1.6.0
验证通过
切换到 1.5.0 再运行(注意 1.5.0 主 jar 文件名不同):
sudo ln -sfn commons-email-1.5.0 versions/current
readlink versions/current
java -Dfile.encoding=UTF-8 -cp ".:versions/current/commons-email-1.5.jar:versions/current/lib/*" HelloEmail
实测回显:
commons-email-1.5.0
邮件已发送, Message-ID: <250075633.0.1791910557049@localhost>
commons-email 版本: 1.5
验证通过
程序打印的版本号随符号链接同步变化,证明切换生效。切回最新版:
sudo ln -sfn commons-email-1.6.0 versions/current
该命令无输出。这套机制的关键约束是:编译和运行都必须引用 current 路径,任何一处写死版本号目录,切换都会失效。
七、卸载
卸载分三部分:手动安装目录、Maven 本地仓库缓存、以及不再需要时的 JDK/Maven 本身。清理手动安装目录与 Maven 验证工程:
sudo rm -rf /opt/mail /opt/mail-demo
该命令无输出。Maven 本地仓库中 commons-email 相关缓存的体积与清理:
du -sh ~/.m2/repository/org/apache/commons/commons-email
rm -rf ~/.m2/repository/org/apache/commons/commons-email
实测回显(第一条命令):
104K /root/.m2/repository/org/apache/commons/commons-email
若 JDK 17 与 Maven 也不再有他用,可一并卸载:
sudo apt remove -y openjdk-17-jdk maven
sudo apt autoremove -y
java -version
mvn -v
实测回显(节选,实测首尾):
Removing maven (3.6.3-5) ...
Removing openjdk-17-jdk:amd64 (17.0.20.1+1-1~22.04) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
bash: java: command not found
bash: mvn: command not found
java/mvn 命令消失即卸载完成。注意:~/.m2 中其他项目的依赖缓存不受本次卸载影响,若要彻底清空可再执行 rm -rf ~/.m2。
八、FAQ
Q1:java -jar commons-email-1.6.0.jar 为什么报 no main manifest attribute?
因为 Commons Email 是纯库,jar 清单里没有 Main-Class,本质上不是命令行工具。要运行自己的代码,改用 java -cp "主jar:lib/*" 你的主类 的方式(见第四章实测命令)。
Q2:程序里打印的中文在终端显示成问号或乱码怎么办?
这是 locale 问题而不是库的问题。实测未设置 locale 时程序输出会退回 ASCII。解决:把 export LANG=C.UTF-8 写入 ~/.bashrc,或运行时追加 -Dfile.encoding=UTF-8。
Q3:运行报 NoClassDefFoundError: javax/mail/MessagingException 怎么处理?
说明 JavaMail 依赖不在类路径里。1.6.0 需要 com.sun.mail:jakarta.mail:1.6.7 与 com.sun.activation:jakarta.activation:1.2.1(见第三章 dependency:tree 实测)。Maven 项目按坐标补依赖即可;手动部署则把对应 jar 放进 lib/。
Q4:怎么确认运行的就是我想要的版本?
用第三章 HelloEmail 里的 Email.class.getPackage().getImplementationVersion(),它读取 jar 清单里的 Implementation-Version,实测 1.6.0 打印 commons-email 版本: 1.6.0、1.5.0 打印 1.5。Maven 场景还可以用 mvn dependency:tree 核对解析结果。
Q5:downloads.apache.org 上找不到 1.6.0 怎么办?
官方主下载目录只现挂 2.0.0 里程碑版,1.6.0 稳定版在归档站 https://archive.apache.org/dist/commons/email/binaries/(本文实测即从此处下载)。更推荐直接从 Maven 中央仓库 https://repo1.maven.org/maven2/org/apache/commons/commons-email/1.6.0/ 按版本取 jar。
九、参考链接
- Apache Commons Email 官方主页:https://commons.apache.org/proper/commons-email/
- 1.6.0 发行包下载:https://archive.apache.org/dist/commons/email/binaries/commons-email-1.6.0-bin.tar.gz
- 发行包 sha512 校验文件:https://archive.apache.org/dist/commons/email/binaries/commons-email-1.6.0-bin.tar.gz.sha512
- Maven 中央仓库 1.6.0 目录(含 pom 与 jar):https://repo1.maven.org/maven2/org/apache/commons/commons-email/1.6.0/
- Apache 归档下载站(历史版本):https://archive.apache.org/dist/commons/email/binaries/
- 官方 javadoc(1.6.0 在线 API 文档):https://commons.apache.org/proper/commons-email/apidocs/index.html
- OpenJDK 17 Ubuntu 安装文档:https://packages.ubuntu.com/jammy/openjdk-17-jdk
- Maven 安装文档:https://maven.apache.org/install.html