I am trying to build an email client app in android and right now i want to configure the javaMail part.
i am trying to establish the connection with the imap server but something is wrong with my code.. here is my code:
package mailpackage; import java.util.Properties; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.NoSuchProviderException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Store; public class Connection implements Runnable { boolean done; public Connection() { this.done=false; } @Override public void run() { System.out.println("Hello from Connection Thread!"); while(!done) { String host = "myhost";// change accordingly String mailStoreType = "imap"; String username = "myusername";// change accordingly String password = "mypasswd";// change accordingly check(host, mailStoreType, username, password); } } public static void receiveEmail(String host, String storeType, String username, String password) { try { Properties properties = new Properties(); properties.put("mail.imap.com", host); properties.put("mail.imap.starttls.enable","true"); properties.put("mail.imap.auth", "true"); // If you need to authenticate // Use the following if you need SSL properties.put("mail.imap.socketFactory.port", 993); properties.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); properties.put("mail.imap.socketFactory.fallback", "false"); Session emailSession = Session.getDefaultInstance(properties); emailSession.setDebug(true); //2) create the IMAP store object and connect with the Imap server IMAPStore emailStore = (IMAPStore) emailSession.getStore(storeType); emailStore.connect(host, username, password); //3) create the folder object and open it Folder emailFolder = emailStore.getFolder("INBOX"); emailFolder.open(Folder.READ_ONLY); //4) retrieve the messages from the folder in an array and print it Message[] messages = emailFolder.getMessages(); for (int i = 0; i <messages.length; i++) { Message message = messages[i]; MimeMessage m = new MimeMessage(emailSession); m.setContent(((MimeMessage)messages[i]).getContent() , "text/plain; charset=UTF-8"); System.out.println("---------------------------------"); System.out.println("Email Number " + (i + 1)); System.out.println("Subject: " + message.getSubject()); System.out.println("From: " + message.getFrom()[0]); System.out.println("Text: " + message.getContent().toString()); m.writeTo(System.out); } //5) close the store and folder objects emailFolder.close(false); emailStore.close(); } catch (NoSuchProviderException e) {e.printStackTrace();} catch (MessagingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} } public void stopThread() { this.done=true; } }
I call the thread from another class like this
connec=new Connection(); (new Thread(connec)).start();
I get the Following errors:
javax.mail.MessagingException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:571) at javax.mail.Service.connect(Service.java:288) at javax.mail.Service.connect(Service.java:169) at mailpackage.Connection.check(Connection.java:63) at mailpackage.Connection.run(Connection.java:33) at java.lang.Thread.run(Thread.java:744) Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:882) at sun.security.ssl.AppInputStream.read(AppInputStream.java:102) at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:110) at java.io.BufferedInputStream.fill(BufferedInputStream.java:235) at java.io.BufferedInputStream.read(BufferedInputStream.java:254) at com.sun.mail.iap.ResponseInputStream.readResponse(ResponseInputStream.java:98) at com.sun.mail.iap.Response.<init>(Response.java:96) at com.sun.mail.imap.protocol.IMAPResponse.<init>(IMAPResponse.java:61) at com.sun.mail.imap.protocol.IMAPResponse.readResponse(IMAPResponse.java:135) at com.sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.java:261) at com.sun.mail.iap.Protocol.<init>(Protocol.java:114) at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:104) at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:538) ... 5 more Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323) ... 23 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 29 more
i read something about PKIX path error that says to add the cert to java store as a trusted cert, but i dont know if this is the solution for this, and if it is i dont know how to do it.
// i dont have access to the mail server
Any suggestions? thanks!
This issue might arise if you are using a self-signed certificate or a certificate that's been issued by an internal certificate authority, or if your clients (e.g., browser, Java) are outdated. Trust is handled by having the root and intermediate certificates of your SSL certificate on a trusted keystore.
What does the PKIX path building error mean? PKIX stands for Public Key Infrastructure X509. Whenever Java attempts to connect to another application over SSL, the connection will only succeed if it can trust the application.
If Server returns a certificate that cannot be validated against the certificates a browser or Java client holds in its truststore then it throws the "sun. security. validator. ValidatorException: PKIX path building failed: sun.
Ok problem solved!
The solution is this:
First get the self-signed certificate from the mail server via openssl:
echo | openssl s_client -connect yoursever:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > yourcert.pem
Then save the yourcert.pem file into this path /Library/Java/Home/lib/security (on macOSX) and put the cert file into the cacerts like this
keytool -keystore cacerts -importcert -alias youralias -file yourcert.pem
The default keystore password is changeit
You can view the change that you made with this command that shows the Certificate fingerprint.
keytool -list -keystore cacerts
After this you should pass these argument in VM
(for windows and linux type yourpath between " " )
-Djavax.net.ssl.trustStore="/Library/Java/Home/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"
For Debug:
-Djava.security.debug=certpath
-Djavax.net.debug=trustmanager
You can try upgrade library javax.mail.jar at https://java.net/projects/javamail/pages/Home (now version is 1.5.5) and add code :
MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); properties.put("mail.imap.ssl.trust", "*"); properties.put("mail.imap.ssl.socketFactory", sf);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With