Unable to retrieve emails from Gmail using Java - java

I am trying to write a simple program in Java, in order to check my mailbox and get whatever email is in the inbox.
I have read various tutorials and watched a video in youtube and I found out that most people do something similar to this
So the I have taken the code found there:
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
public class CheckingMails {
public static void check(String host, String storeType, String user,
String password)
{
try {
//create properties field
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.pop3.port", "995");
properties.put("mail.pop3.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(properties);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore("pop3");
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
for (int i = 0, n = messages.length; i < n; i++) {
Message message = messages[i];
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());
}
//close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String host = "pop.gmail.com";// change accordingly
String mailStoreType = "pop3";
String username = "giannisthedrummer2#gmail.com";// change accordingly
String password = "********";// change accordingly
check(host, mailStoreType, username, password);
}
}
But I can't get my mails. Instead this error appears:
javax.mail.AuthenticationFailedException: EOF on socket
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:104)
at javax.mail.Service.connect(Service.java:233)
at javax.mail.Service.connect(Service.java:134)
at CheckingMails.check(CheckingMails.java:29)
at CheckingMails.main(CheckingMails.java:69)
I have enabled the POP and IMAP accesibility features on my email, as well as enabled less secure connections.
I downloaded the necessary .jar files from mail.jar and activation.jar
After looking around a bit, I found out that the issue probably is coming from Google's side, meaning that the authentication is going worng. The password and the name is correct (I have checked that multiple times). I have enabled both IMAP and POP connections and I have allowed less secure connections, but still I get an javax.mail.AuthenticationFailedException error.
Any ideas why is this happening?

You're connecting on the SSL port but not enabling SSL. Follow the Gmail instructions in the JavaMail FAQ. Get rid of the port setting and set mail.pop3.ssl.enable.
And make sure you understand the limitations of pop3 vs. imap.

do below change to your Gmail account to access it from outside
Login to Gmail.
Access the URL as https://www.google.com/settings/security/lesssecureapps
Select "Turn on"

For the people that will struggle in the future in the same way I did:
After applying the suggestion from Bill Shannon, I got another error,which I found out that it was coming due to the fact that I hadn't configure the ssl certificates properly. Since I have little to no clue about those, I was searching around the internet to find
Properties properties = new Properties();
properties.put("mail.imap.host", host);
properties.put("mail.imap.user", user);
properties.setProperty("mail.imap.ssl.enable", "true");
properties.put("mail.imap.ssl.trust", "*");
I changed the pop3 protocol to IMAP, because the later allows me to perform more tasks, but for the sole purpose of retrieving my emails both work in the same way.
The last line, in my understanding will accept any certificate, which probably is not the right way to go about it, but at the moment I don't know which one is the correct one.
Thank you all for your help.
****** It is important that the user, enables the POP3/IMAP connections in their accounts and also turn on the less secure applications, as it was stated previously. ******

Related

How To Detect An Email Address Is Real

IMPORTANT
I have been blocked by hotmail services. There is a control mechanism
called spamhaus which kicked me out. I'm stuck right now.
I am trying to detect an email address is valid and if its valid then check if this email address potentially used (I know that its not certain). For example, lets assume that there is a website with domain myimaginarydomain.com. If I run code below, I guess it won't fail because domain address is valid. But nobody can take an email address with that domain.
Is there any way to find out that email address is valid? (In this case its invalid)
I don't want to send confirmation email
Sending ping may be useful?
public class Application {
private static EmailValidator validator = EmailValidator.getInstance();
public static void main(String[] args) {
while (true) {
Scanner scn = new Scanner(System.in);
String email = scn.nextLine();
boolean isValid = validateEmail(email);
System.out.println("Syntax is : " + isValid);
if (isValid) {
String domain = email.split("#")[1];
try {
int test = doLookup(domain);
System.out.println(domain + " has " + test + " mail servers");
} catch (NamingException e) {
System.out.println(domain + " has 0 mail servers");
}
}
}
}
private static boolean validateEmail(String email) {
return validator.isValid(email);
}
static int doLookup(String hostName) throws NamingException {
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext(env);
Attributes attrs =
ictx.getAttributes(hostName, new String[]{"MX"});
Attribute attr = attrs.get("MX");
if (attr == null) return (0);
return (attr.size());
}
}
There is no failsafe way to do this in all cases, but, assuming the server uses SMTP then https://www.labnol.org/software/verify-email-address/18220/ gives quite a good tutorial on one method that may work.
The method used in the tutorial relies on OS tools, so you will need to ensure they exist before using them. a ProcessBuilder may help. Alternatively, you can open a socket directly in code and avoid using OS-dependent tools.
Essentially, you find out what the mail servers are (using nslookup), then telnet to one of the mail servers and start writing an email:
3a: Connect to the mail server:
telnet gmail-smtp-in.l.google.com 25
3b: Say hello to the other server
HELO
3c: Identify yourself with some fictitious email address
mail from:<labnol#labnol.org>
3d: Type the recipient’s email address that you are trying to verify:
rcpt to:<billgates#gmail.com>
The server response for rcpt to command will give you an idea whether an email address is valid or not. You’ll get an “OK” if the address exists else a 550 error
There really is no sensible way except trying to send a notification with a token to the address and ask the other party to confirm it, usually by visiting a web-page:
the recipients MX may be unavailable at the moment but come back online later, so you cannot rely on a lookup in real time;
just because the MX accepts the email doesn't mean that the address is valid, the message could bounce later down the pipe (think UUCP);
if this is some kind of registration service, you need to provide some confirmation step anyway as otherwise it'd become too easy to subscribe random strangers on the internet that do not want your service.

How to read mail with java mail API (String cannot be cast to Multipart)

I am trying to write a simple code that will read messages from gmail inbox.
I have found some examples, but non of them is working.
Most promising is code I've found on CompilatimEerror.com, BUT whatever I try I get this error:
java.lang.ClassCastException: java.lang.String cannot be cast to javax.mail.Multipart
Here is my code:
import java.util.*;
import javax.mail.*;
public class ReadingEmail {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getInstance(props, null);
Store store = session.getStore();
store.connect("imap.gmail.com", "yourEmailId#gmail.com","password");
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
Message msg = inbox.getMessage(inbox.getMessageCount());
Address[] in = msg.getFrom();
for (Address address : in) {
System.out.println("FROM:" + address.toString());
}
Multipart mp = (Multipart) msg.getContent(); // here it breaks
BodyPart bp = mp.getBodyPart(0);
System.out.println("SENT DATE:" + msg.getSentDate());
System.out.println("SUBJECT:" + msg.getSubject());
System.out.println("CONTENT:" + bp.getContent());
} catch (Exception mex) {
mex.printStackTrace();
}
}
}
There is no connection error, as it gets the subject, date, and all this stuff, but the email body is a mystery. There will be no attachments, I will get only simple mails(this is a part of greater project)
What I am looking for is to read the unread mail (and then delete this message, so the inbox will be permanently empty(spam will be deleted manually)).
I lack knowledge about web programing/structures, and all that pop's, imaps and stuff is a blank space.
Also keep in mind that I am a novice programmer and this is the first time that I go outside of my computer with my code unfortunately straight into the problems of protocols / authentication / getting things from internet.
I went through a lot of pages, but never found an explanation that would allow me to create it myself...
Are you related to this guy?
The JavaMail FAQ has pointers to lots of helpful information, including the JavaMail project page, sample code, etc. You'll also find pointers to some useful background material and tutorials here.

How to access gmail account via javamail

I try to access email account on a certain email server via "imap" through java mail. I did some research on this. And I find the following code which works for gmail.
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
public class DeleteMessageExample {
public static void main (String args[]) throws Exception {
String host = args[0];
String username = args[1];
String password = args[2];
// Get session
Session session = Session.getInstance(
System.getProperties(), null);
// Get the store
Store store = session.getStore("imaps");
store.connect(host, username, password);
// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
BufferedReader reader = new BufferedReader (
new InputStreamReader(System.in));
// Get directory
Message message[] = folder.getMessages();
for (int i=0, n=message.length; i<n; i++) {
System.out.println(i + ": " + message[i].getFrom()[0]
+ "\t" + message[i].getSubject());
System.out.println("Do you want to delete message? [YES to delete]");
String line = reader.readLine();
// Mark as deleted if appropriate
if ("YES".equals(line)) {
message[i].setFlag(Flags.Flag.DELETED, true);
}
}
// Close connection
folder.close(true);
store.close();
}
}
However, I need to specify the args[0] to be imap.gmail.com args[1] to be usrname, args[2] to be password. And if I replace imap.gmail.com by the ip address 74.125.224.86, it no longer work.
My question is suppose I have an account on yahoo mail, what the hostname I should use?
I tried imap.yahoo.com, mail.yahoo.com and the ip address.
If you know the answer, would you mind also told me what is the regular rule to find out what kind hostname I should use?
Thanks a lot.
Unlike Gmail, Yahoo Mail's IMAP services is not a totally standard IMAP service. You need send some special tokens before you login. You need to modify the JavaMail API in order to connect to Yahoo Mail through IMAP. The latest JavaMail 1.4.4-SNAPSHOT release supports Yahoo Mail as well. You can get it here

Can I perform a search on mail server in Java?

I am trying to perform a search of my gmail using Java. With JavaMail I can do a message by message search like so:
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "myUsername", "myPassword");
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_ONLY);
SearchTerm term = new SearchTerm() {
#Override
public boolean match(Message mess) {
try {
return mess.getContent().toString().toLowerCase().indexOf("boston") != -1;
} catch (IOException ex) {
Logger.getLogger(JavaMailTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (MessagingException ex) {
Logger.getLogger(JavaMailTest.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
};
Message[] searchResults = inbox.search(term);
for(Message m:searchResults)
System.out.println("MATCHED: " + m.getFrom()[0]);
But this requires downloading each message. Of course I can cache all the results, but this becomes a storage concern with large gmail boxes and also would be very slow (I can only imagine how long it would take to search through gigabytes of text...).
So my question is, is there a way of searching through mail on the server, a la gmail's search field? Maybe through Microsoft Exchange?
Hours of Googling has turned up nothing.
You can let the server do the search for you, with the appropriate IMAP command. The SEARCH command will only get you so far, what you probably need is the SORT command. SORT isn't implemented in JavaMail but the documentation shows how you can implement it yourself:
http://java.sun.com/products/javamail/javadocs/com/sun/mail/imap/IMAPFolder.html#doCommand(com.sun.mail.imap.IMAPFolder.ProtocolCommand)
(I couldn't figure out how to link to a URL with parentheses)
Connect to the Exchange IMAP store and use javax.mail.search.SearchTerm

Someone knows a mail (SMTP) delivery library for Java?

I'd like to send mail without bothering with the SMTP-Server which is used for delivery.
So JavaMail API doesn't work for me because I have to specify a SMTP server to connect to.
I'd like the library to find out on its own which SMTP server is responsible for which email address by querying the MX record of the mail address domain.
I'm looking for something like Aspirin. Unfortunately I can't use Aspirin itself because the development stopped 2004 and the library fails to communicate with modern spam hardened servers correctly.
An embeddable version of James would do the task. But I haven't found documentation concerning whether this is possible.
Or does anyone know about other libraries I could use?
One possible solution: get the MX record on your own and use JavaMail API.
You can get the MX record using the dnsjava project:
Maven2 dependency:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>2.0.1</version>
</dependency>
Method for MX record retrieval:
public static String getMXRecordsForEmailAddress(String eMailAddress) {
String returnValue = null;
try {
String hostName = getHostNameFromEmailAddress(eMailAddress);
Record[] records = new Lookup(hostName, Type.MX).run();
if (records == null) { throw new RuntimeException("No MX records found for domain " + hostName + "."); }
if (log.isTraceEnabled()) {
// log found entries for debugging purposes
for (int i = 0; i < records.length; i++) {
MXRecord mx = (MXRecord) records[i];
String targetString = mx.getTarget().toString();
log.trace("MX-Record for '" + hostName + "':" + targetString);
}
}
// return first entry (not the best solution)
if (records.length > 0) {
MXRecord mx = (MXRecord) records[0];
returnValue = mx.getTarget().toString();
}
} catch (TextParseException e) {
throw new RuntimeException(e);
}
if (log.isTraceEnabled()) {
log.trace("Using: " + returnValue);
}
return returnValue;
}
private static String getHostNameFromEmailAddress(String mailAddress) throws TextParseException {
String parts[] = mailAddress.split("#");
if (parts.length != 2) throw new TextParseException("Cannot parse E-Mail-Address: '" + mailAddress + "'");
return parts[1];
}
Sending mail via JavaMail code:
public static void sendMail(String toAddress, String fromAddress, String subject, String body) throws AddressException, MessagingException {
String smtpServer = getMXRecordsForEmailAddress(toAddress);
// create session
Properties props = new Properties();
props.put("mail.smtp.host", smtpServer);
Session session = Session.getDefaultInstance(props);
// create message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(fromAddress));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
msg.setSubject(subject);
msg.setText(body);
// send message
Transport.send(msg);
}
This is completely the wrong way to handle this.
Anyone connected to the internet will have some kind of "legit" SMTP server available to them to take the submission of email -- your ISP, your office, etc.
You WANT to leverage because they do several things for you.
1) they take your message and the responsibility to handle that message. After you drop it off, it's not your problem anymore.
2) Any mail de-spamming technologies are handled by the server. Even better, when/if those technologies change (Domain keys anyone?), the server handles it, not your code.
3) You, as a client of that sending mail system, already have whatever credentials you need to talk to that server. Main SMTP servers are locked down via authentication, IP range, etc.
4) You're not reinventing the wheel. Leverage the infrastructure you have. Are you writing an application or a mail server? Setting up mail server is an every day task that is typically simple to do. All of those casual "dumb" users on the internet have managed to get email set up.
Don't.
Sending email is much more complex than it seems. Email servers excel at (or should excel at) reliable delivery.
Set up a separate email server if you need to- that will be essentially the same as implementing one in Java (I doubt you will find libraries for this task- they would be essentially complete mail servers), but much more simpler.

Categories

Resources