Tomcat9环境下JSP密码恢复系统JavaMail SSL握手异常求助
Java JSP项目Tomcat部署下JavaMail SSL握手错误排查
我正在开发部署于Tomcat 9的Java JSP项目,采用PostgreSQL存储数据,核心功能是通过JavaMail API实现密码恢复邮件发送,但持续遭遇SSL握手错误导致邮件发送失败。
项目环境配置
- Java版本:OpenJDK 21.0.4 LTS (Temurin)
openjdk version "21.0.4" 2024-07-16 LTS OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)
- 技术栈:JSP+Java Servlet实现前后端逻辑
- 服务器:Windows环境Tomcat 9,配置如下:
- JRE路径:C:\Program Files\Java\jdk1.7.0_80\jre
- JDK路径:C:\Program Files\Java\jdk1.7.0_80
- Tomcat路径:C:\Program Files\Apache Software Foundation\Tomcat 9.0
- Catalina配置路径:C:\Program Files\Apache Software Foundation\Tomcat 9.0\conf\Catalina
- 数据库:PostgreSQL 42.2.29驱动(PostgreSQL JDBC)
核心错误信息
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171) at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:101) at sun.security.ssl.TransportContext.kickstart(TransportContext.java:238) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:394) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373) at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549) at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:354) at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:237) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1927)
使用的依赖库
- PostgreSQL JDBC (postgresql-42.2.29.jre7.jar)
- Bcrypt (jbcrypt-0.4.jar)
- JavaMail API (mail-1.4.7.jar, smtp-1.6.2.jar, javax.activation.jar)
- 安全策略包(US_export_policy.jar, local_policy.jar)
- 额外添加库:US_export_policy.jar、bcrypt-0.4.1.jar等共9个JAR包
邮件发送核心代码(RECOVERY_ACCOUNT.JSP)
// THIS IS THE MAIN CODE THAT IS SENDING EMAILS (RECOVERY_ACCOUNT.JSP) // Database connection configurations String url = "jdbc:postgresql://localhost:5432/bibliotech"; String user = "postgres"; String password = "admin"; String email = request.getParameter("email"); String passwordHash = null; try { // Connect to the database Class.forName("org.postgresql.Driver"); Connection conn = DriverManager.getConnection(url, user, password); // Query to check if the email exists String query = "SELECT password_hash FROM USERS WHERE email = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, email); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { passwordHash = rs.getString("password_hash"); // Retrieve the password hash } else { out.println("<script>alert('Email not found!'); window.location.href = 'recovery.jsp';</script>"); } rs.close(); pstmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } // If the password hash was found, send an email to the user if (passwordHash != null) { // JavaMail configurations String host = "smtp.gmail.com"; // Using Gmail as an example String from = "bibliotechproject@gmail.com"; // Your email String appPassword = "************"; // Use a Gmail app password String to = email; String subject = "Password Recovery - Bibliotech"; // Email content with HTML String messageText = "<div style='font-family: Arial, sans-serif; padding: 20px; background-color: #f4f4f4;'>" + "<center>" + "<img src='https://iili.io/dPzedMX.png' alt='Account Recovery' style='width: 100%; max-width: 600px; height: auto;'>" + "<div style='background-color: #ffffff; padding: 20px; border-radius: 8px; max-width: 600px; text-align: left;'>" + "<h2 style='color: #333;'>Account Recovery</h2>" + "<p style='color: #555;'>Hello,</p>" + "<p style='color: #555;'>We received a request to recover the password for your account. Here are your login details:</p>" + "<p style='font-weight: bold; color: #333;'>Email: " + email + "</p>" + "<p style='font-weight: bold; color: #333;'>Password: " + passwordHash + "</p>" + "<p style='color: #555;'>If you did not make this request, please ignore this email.</p>" + "<p style='color: #555;'>Sincerely, https://prod.liveshare.vsengsaas.visualstudio.com/join?01A2BDE3A14A18BC1D1E0892E16E13D31189</p>" + "<p style='color: #333; font-weight: bold;'>Support Team - Bibliotech</p>" + "</div>" + "</center>" + "</div>"; Properties props = System.getProperties(); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", host); props.put("mail.smtp.user", from); props.put("mail.smtp.password", appPassword); props.put("mail.smtp.port", "587"); props.put("mail.debug", "true"); props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.auth", "true"); Session mailSession = Session.getDefaultInstance(props, null); MimeMessage message = new MimeMessage(mailSession); try { message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject(subject); message.setContent(messageText, "text/html"); Transport transport = mailSession.getTransport("smtp"); transport.connect(host, from, appPassword); transport.sendMessage(message, message.getAllRecipients()); transport.close(); response.sendRedirect("send_success.jsp"); } catch (Exception e) { e.printStackTrace(); } }
已尝试措施
- 确认服务器及JavaMail配置启用正确SSL协议
- 更新JavaMail库尝试解决SSL协议不匹配
- 检查JAR包顺序排查冲突
疑问
- 异常是否与Java21版本、JavaMail或Tomcat配置有关?
- 是否因旧版JAR包导致SSL协议冲突?
- 同类问题的解决方案是什么?
- 正确的依赖版本及顺序是怎样的?
此外,曾有一天无需修改即可正常发送邮件,次日同一机器再次出现错误,怀疑与Java配置相关。
内容的提问来源于stack exchange,提问作者JonathanDEVOPS
相关产品推荐
相关产品推荐

