I have this code:
public class JavaApplication3 {
private String smtpHost = "mail.medirom-lab.ro"; // SMTP server host
private String smtpPort = "465"; // SMTP server port
private String smtpUsername = "[email protected]"; // SMTP username
private String smtpPassword = "***********"; // SMTP password
public static void main(String[] args) {
JavaApplication3 sender = new JavaApplication3();
sender.sendEmail("[email protected]", "[email protected]", "Subject", "Body", null);
}
public void sendEmail(String from, String to, String subject, String body, List<String> attachments) {
try {
Properties props = new Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
//props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.socketFactory", new BouncyCastleSSLSocketFactory());
props.put("mail.debug", "true");
props.put("mail.smtp.localhost", smtpHost);
props.put("mail.smtp.transport", "smtps");
// Authenticator (username and password)
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(smtpUsername, smtpPassword);
}
};
// Create Session instance with properties and authenticator
Session session = Session.getInstance(props, authenticator);
System.out.println("JavaMail version: " + session.getProperty("mail.version"));
System.out.println("Java version: " + System.getProperty("java.version"));
for (String key : props.stringPropertyNames()) {
System.out.println(key + ": " + props.getProperty(key));
}
// Create MimeMessage
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
// Create multipart content if there are attachments
if (attachments != null && !attachments.isEmpty()) {
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(body);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
message.setContent(multipart);
} else {
message.setText(body);
}
// Send the message
Transport.send(message);
System.out.println("Email sent successfully.");
} catch (Exception ex) {
ex.printStackTrace();
System.err.println("Error sending email: " + ex.getMessage());
}
}
class BouncyCastleSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;
public BouncyCastleSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
try {
if (Security.getProvider("BC") == null) {
Security.addProvider(new BouncyCastleProvider());
}
if (Security.getProvider("BCJSSE") == null) {
Security.addProvider(new org.bouncycastle.jsse.provider.BouncyCastleJsseProvider());
}
String[] protocols = SSLContext.getDefault().getSupportedSSLParameters().getProtocols();
System.out.println("Supported SSL/TLS protocols:");
for (String protocol : protocols) {
System.out.println("Protocol: "+protocol);
}
for (Provider provider : Security.getProviders()) {
System.out.println("Sec provider is: "+provider.getName());
}
// Use TLS protocol with Bouncy Castle provider
SSLContext sslContext = SSLContext.getInstance("TLSv1.2", "BCJSSE");
sslContext.init(null, null, null);
delegate = sslContext.getSocketFactory();
} catch (NoSuchProviderException ex) {
Logger.getLogger(JavaApplication3.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return delegate.createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return delegate.createSocket(host, port);
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
return delegate.createSocket(host, port, localAddress, localPort);
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return delegate.createSocket(host, port);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return delegate.createSocket(address, port, localAddress, localPort);
}
}
}
And it works fine on a minimal setup, just this file but when I move this file on the production environment I can no longer send mails because isSSL is false.
I can find no difference between the setups:
- Both use JDK 1.8, Bouncy Castle 1.78.1, javax.mail-1.6.0-rc2.
- the computer is the same and when I run the apps I use the same JDK instance and the same IDE
- In the VM options I have no significant changes, in the project that is working I have nothing, in the one that is not working I have “-Xms1140m -Xmx1140m “
The error is:
DEBUG: JavaMail version 1.4ea
DEBUG: successfully loaded file: C:Program FilesJavajdk1.8.0_202jrelibjavamail.providers
DEBUG: !anyLoaded
DEBUG: not loading resource: /META-INF/javamail.providers
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: !anyLoaded
DEBUG: not loading resource: /META-INF/javamail.address.map
DEBUG: successfully loaded file: C:Program FilesJavajdk1.8.0_202jrelibjavamail.address.map
JavaMail version: null
mail.smtp.port: 465
mail.debug: true
mail.smtp.socketFactory.fallback: false
mail.smtp.auth: true
mail.smtp.host: mail.medirom-lab.ro
mail.smtp.localhost: mail.medirom-lab.ro
mail.smtp.ssl.enable: true
mail.smtp.transport: smtps
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "mail.medirom-lab.ro", port 465, isSSL false
DEBUG SMTP: EOF: [EOF]
DEBUG SMTP: could not connect to host "mail.medirom-lab.ro", port: 465, response: -1
On both projects I have the same security providers and the same supported protocols:
Supported SSL/TLS protocols:
Protocol: SSLv2Hello
Protocol: SSLv3
Protocol: TLSv1
Protocol: TLSv1.1
Protocol: TLSv1.2
Sec provider is: SUN
Sec provider is: SunRsaSign
Sec provider is: SunEC
Sec provider is: SunJSSE
Sec provider is: SunJCE
Sec provider is: SunJGSS
Sec provider is: SunSASL
Sec provider is: XMLDSig
Sec provider is: SunPCSC
Sec provider is: SunMSCAPI
Sec provider is: BC
Sec provider is: BCJSSE