Problem mit JavaMail API

Guten Tag/Abend!
Ich habe ein Problem mit der JavaMail API das Problem ist das ich bei start des Programms immer eine Exception bekomme!
Der Zweck des Programms besteht darin das man mit der login Methode eine Instance der Klasse erstellt und verschiedene Sachen mit den Emails machen kann.

Exception:

javax.mail.MessagingException: 220 smtp.gmail.com ESMTP k8sm4882723edn.52 - gsmtp;
nested exception is:
com.sun.mail.iap.ConnectionException: 220 smtp.gmail.com ESMTP k8sm4882723edn.52 - gsmtp
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:738)
at javax.mail.Service.connect(Service.java:366)
at javax.mail.Service.connect(Service.java:246)
at ********.Mail.<init>(Mail.java:80)
at ********.Mail.login(Mail.java:29)
at Main.main(Main.java:7)
Caused by: com.sun.mail.iap.ConnectionException: 220 smtp.gmail.com ESMTP k8sm4882723edn.52 - gsmtp
at com.sun.mail.imap.protocol.IMAPProtocol.processGreeting(IMAPProtocol.java:341)
at com.sun.mail.iap.Protocol.<init>(Protocol.java:141)
at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:131)
at com.sun.mail.imap.IMAPStore.newIMAPProtocol(IMAPStore.java:763)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:698)
... 5 more
Code:

Java:
package ******;

import java.util.*;
import javax.mail.*;
import javax.mail.Flags.Flag;
import javax.mail.internet.*;

import com.sun.mail.imap.IMAPStore;

import *******.providers.Providers;

public class Mail {

    private String email;
    private Session session;
    private IMAPStore imapStore;
    private String username;
    private int imap_port;
    private String imap_host;
    private int smtp_port;
    private String smtp_host;
    private int pop3_port;
    private String pop3_host;
    
    public static Mail login(String email, String password, String username, Providers provider) {
        System.out.println("Anbieter: " + provider.getName());
        provider.printInfos();
        
        return new Mail(email, password, username, provider.getIMAPHost(), provider.getIMAPPort(), provider.getSMTPHost(), provider.getSMTPPort(), provider.getPOP3Host(), provider.getPOP3Port());
    }
    
    private Authenticator getAuthenticator(String email, String password) {
        PasswordAuthentication passAuth = new PasswordAuthentication(email, password);
        Authenticator auth = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return passAuth;
            }
        };
        
        return auth;
    }
    
    private Properties getProps() {
        Properties props = new Properties();
        
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", this.smtp_host);
        props.put("mail.smtp.socketFactory.port", String.valueOf(this.smtp_port));
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", String.valueOf(this.smtp_port));
        
        props.put("mail.store.protocol", "imaps");
        
        props.put("mail.imaps.port", String.valueOf(this.imap_port));
        props.put("mail.imaps.starttls.enable", "true");
        
        props.put("mail.pop3.starttls.enable", "true");
        props.put("mail.pop3.host", this.pop3_host);
        props.put("mail.pop3.port", String.valueOf(this.pop3_port));
        
        return props;
    }
    
    private Mail(String fromEmail, String password, String username, String imap_host, int imap_port, String smtp_host, int smtp_port, String pop3_host, int pop3_port) {
        try {
            this.imap_host = imap_host;
            this.imap_port = imap_port;
            this.smtp_host = smtp_host;
            this.smtp_port = smtp_port;
            this.pop3_host = pop3_host;
            this.pop3_port = pop3_port;
            
            System.out.println("Einloggen...");
            
            session = Session.getDefaultInstance(getProps(), getAuthenticator(fromEmail, password));
            Store store = session.getStore("imaps");
            
            store.connect(this.imap_host, username, password);
            
            imapStore = (IMAPStore) store;
            
            System.out.println("Eingeloggt!");
            System.out.println("E-Mail: " + fromEmail);
            System.out.println("Benutzername: " + username);
            System.out.println("Passwort: " + password);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public void send(String email, String subject, String text, String description, String charset) {
        try {
            MimeMessage message = new MimeMessage(session);
            
            System.out.println("Versende...");
            
            message.setFrom(new InternetAddress(this.email, username));
            message.setReplyTo(InternetAddress.parse(email, false));
            message.setSubject(subject);
            message.setText(text, charset);
            message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(email));
            message.setSentDate(new Date());
            message.setDescription(description, charset);
            
            Transport.send(message);
            System.out.println("E-Mail versendet!");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public void check() {
        try {
            Folder folder = imapStore.getFolder("INBOX");
            
            folder.open(Folder.READ_ONLY);
            
            System.out.println("Nachrichten: " + folder.getMessageCount());
            System.out.println("Neue Nachrichten: " + folder.getNewMessageCount());
            System.out.println("Ungelesene Nachrichten: " + folder.getUnreadMessageCount());
            System.out.println("Gelöschte Nachrichten: " + folder.getDeletedMessageCount());
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public void checkEmail(int i) {
        try {
            Folder folder = imapStore.getFolder("INBOX");
            
            folder.open(Folder.READ_ONLY);
            
            Message message = folder.getMessage(i);
            
            if(!message.isSet(Flag.SEEN)) {
                System.out.println("Datum/Uhrzeit: " + message.getReceivedDate());
                System.out.println("Von: " +  Arrays.toString(message.getFrom()));
                System.out.println("Betreff: " + message.getSubject());
                System.out.println("Inhalt: " + message.getContent());
                System.out.println("Beschreibung: " + message.getDescription());
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public void checkEmails() {
        try {
            Folder folder = imapStore.getFolder("INBOX");
            
            folder.open(Folder.READ_ONLY);

            for(int i = 1; i < folder.getMessageCount(); i++) {
                System.out.println("====================================");
                checkEmail(i);
                System.out.println("====================================");
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public String[] getEmails() {
        try {
            Folder folder = imapStore.getFolder("INBOX");
            String[] str = new String[folder.getMessageCount()];
            
            folder.open(Folder.READ_ONLY);
            
            for(int i = 1; i < folder.getMessageCount(); i++) {
                str[i] = folder.getMessage(i).getSubject();
            }
            
            return str;
        } catch(Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    public void setEmailFlag(int i, Flag flag, boolean bool) {
        try {
            Folder folder = imapStore.getFolder("INBOX");
            
            folder.open(Folder.HOLDS_FOLDERS);
            folder.getMessage(i).setFlag(flag, bool);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
}
Was den Code angeht ist er nicht der beste.
 
Welches Protokoll denn und welcher Provider? Empfangen oder Verschicken?
In dem Programm wird SMTP und IMAP verwendet.

Zu deiner zweiten Frage:

Man soll senden und empfangen können.

Und ich habe mir eine eigene Provider Klasse/Enum erstellt:

Java:
package *******.providers;

public enum Providers {

    GOOGLE("Google", "smtp.gmail.com", 465 , "imap.gmail.com", 993, "pop.gmail.com", 995),
    STRATO("STRATO", "smtp.strato.de", 465, "imap.strato.de", 993, "pop3.strato.de", 995),
    GMX("GMX", "mail.gmx.net", 587, "imap.gmx.net", 993, "pop.gmx.net", 995),
    YAHOO("Yahoo", "smtp.mail.yahoo.com", 465, "imap.mail.yahoo.com", 993, "pop.mail.yahoo.com", 995),
    OUTLOOK("Outlook", "SMTP.office365.com", 587, "Outlook.office365.com", 993, "Outlook.office365.com", 995),
    MAIL_DE("Mail.de", "smtp.mail.de", 465, "imap.mail.de", 993, "pop.mail.de", 995),
    WEB_DE("WEB.DE", "smtp.web.de", 587, "imap.web.de", 993, "pop3.web.de", 995);
    
    String name;
    String smtp_host;
    int smtp_port;
    String imap_host;
    int imap_port;
    String pop3_host;
    int pop3_port;
    
    Providers(String providerName, String smtp_host, int smtp_port, String imap_host, int imap_port, String pop3_host, int pop3_port) {
        this.name = providerName;
        this.smtp_host = smtp_host;
        this.smtp_port = smtp_port;
        this.imap_host = imap_host;
        this.imap_port = imap_port;
        this.pop3_host = pop3_host;
        this.pop3_port = pop3_port;
    }
    
    public String getName() {
        return name;
    }
    
    public String getSMTPHost() {
        return smtp_host;
    }
    
    public int getSMTPPort() {
        return smtp_port;
    }
    
    public String getIMAPHost() {
        return smtp_host;
    }
    
    public int getIMAPPort() {
        return smtp_port;
    }
    
    public String getPOP3Host() {
        return pop3_host;
    }
    
    public int getPOP3Port() {
        return pop3_port;
    }
    
    public void printInfos() {
        System.out.println("IMAP-Host: " + imap_host);
        System.out.println("IMAP-Port: " + imap_port);
        System.out.println("SMTP-Host: " + smtp_host);
        System.out.println("SMTP-Port: " + smtp_port);
        System.out.println("POP3-Host: " + pop3_host);
        System.out.println("POP3-Port: " + pop3_port);
    }
    
}
 
K

kneitzel

Also es sieht so aus, als ob Du irgendwo Ports durcheinander wirfst. Die Exception tritt bei einer IMAP Verbindung auf aber die Exception gibt im Text klar, dass Du auf dem smtp Port gelandet bist.
 
Wie kann ich das Problem denn nun beheben?
Ich habe eigentlich schon alles versucht.

(Und wirklich alles)
 
K

kneitzel

Wie kann ich das Problem denn nun beheben?
Ich habe eigentlich schon alles versucht.

(Und wirklich alles)
Das sehe ich so auf Anhieb auch nicht ... gib doch mal vor dem connect etwas mehr Infos aus oder starte im Debugger, so dass Du Dir das ansehen kannst so dass Du siehst, ob die Werte richtig sind oder nicht.

sieht doch richtig aus
Im Stacktrace der Exception ist klar zu sehen, dass smtp.gmail.com sich mit 220 meldet (==> smtp) und er im Code aber im IMAPStore ist. Und natürlich können die IMAP Klassen kein smtp. Daher muss da irgendwo der Wurm drin sein.
 
Es passiert aber alles hier:

Java:
store.connect(this.imap_host, username, password);
Aber es wird alles richtig übergeben.
Nur versteh ich nicht warum denn der Fehler kommt obwohl alles richtig ist.
 
Hier mal die ganze Konsole:

Anbieter: Google
IMAP-Host: imap.gmail.com
IMAP-Port: 993
SMTP-Host: smtp.gmail.com
SMTP-Port: 465
POP3-Host: pop.gmail.com
POP3-Port: 995
Einloggen...
smtp.gmail.com <- Das wird vor connect ausgegeben.
Dann07 <----------
*********** <- Passwort Zensiert
javax.mail.MessagingException: 220 smtp.gmail.com ESMTP c32sm4670507eda.97 - gsmtp;
nested exception is:
com.sun.mail.iap.ConnectionException: 220 smtp.gmail.com ESMTP c32sm4670507eda.97 - gsmtp
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:738)
at javax.mail.Service.connect(Service.java:366)
at javax.mail.Service.connect(Service.java:246)
at *******.Mail.<init>(Mail.java:83)
at *******.Mail.login(Mail.java:29)
at Main.main(Main.java:7)
Caused by: com.sun.mail.iap.ConnectionException: 220 smtp.gmail.com ESMTP c32sm4670507eda.97 - gsmtp
at com.sun.mail.imap.protocol.IMAPProtocol.processGreeting(IMAPProtocol.java:341)
at com.sun.mail.iap.Protocol.<init>(Protocol.java:141)
at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:131)
at com.sun.mail.imap.IMAPStore.newIMAPProtocol(IMAPStore.java:763)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:698)
... 5 more
 
K

kneitzel

Nach dem Einloggen gibst du smtp.gmail.com aus. Woher kommt diese Ausgabe?

Einloggen... gibst du vor dem imap connect aus, also erwarte ich da dann immer den imap host und nicht smtp.
 
Ich kapier auch nicht warum da steht SMTP.
Obwohl ich ja eigentlich IMAP übergebe nix anderes.
Entweder bin ich zu dumm oder ich lass die Sache.
 
Ich habe nun die Lösung gefunden.
Es lag an dem Enum!

Es wurde immer SMTP übergeben.

Java:
    public String getIMAPHost() {
        return smtp_host;
    }
    
    public int getIMAPPort() {
        return smtp_port;
    }
Richtig währe:

Java:
    public String getIMAPHost() {
        return imap_host;
    }
    
    public int getIMAPPort() {
        return imap_port;
    }
 
K

kneitzel

Ich habe nun die Lösung gefunden.
Es lag an dem Enum!

Es wurde immer SMTP übergeben.

Java:
    public String getIMAPHost() {
        return smtp_host;
    }
   
    public int getIMAPPort() {
        return smtp_port;
    }
Richtig währe:

Java:
    public String getIMAPHost() {
        return imap_host;
    }
   
    public int getIMAPPort() {
        return imap_port;
    }
Super. Generell evtl. Noch ein paar Hinweise:
a) schau mal, ob Dir ein Logging Framework gefällt. Statt Ausgaben zu machen logst du dann nur. Hat den Vorteil, dass dies dann drin bleibt und du immer über den Loglevel sagen kannst, was Dich interessiert. Ich bin viel mit slf4j unterwegs, aber es gibt da ganz viel wie z.B, log4j und co.
Und wenn du das nicht willst: gib immer mehr als nur eine Variable aus, so dass du weißt, was wann wo ausgegeben wird, sonst wird die Zuweisung ggf schwer.

Ansonsten wünsche ich weiter viel Erfolg und schön, dass das Problem gelöst werden konnte.
 
Also das klappt bei mir:
Java:
import java.io.IOException;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeMultipart;

public class Mail {
  public static void main(String[] args) throws MessagingException, IOException {
    String host = "?.?.?";
    String user = "";
    String password = "";

    Properties properties = System.getProperties();
    properties.setProperty("mail.pop3.ssl.trust", "*"); // Trust all Servers
    Session session = Session.getDefaultInstance(properties);
    Store store = session.getStore("pop3s");
    store.connect(host, 995, user, password);
    Folder inbox = store.getFolder("Inbox");
    inbox.open(Folder.READ_ONLY);

    Message[] messages = inbox.getMessages();

    if (messages.length == 0)
      System.out.println("No messages found.");

    for (int i = 0; i < messages.length; i++) {
      if (i > 10) {
        System.exit(0);
        inbox.close(true);
        store.close();
      }

      System.out.println("Message " + (i + 1));
      System.out.println("From : " + messages[i].getFrom()[0]);
      System.out.println("Subject : " + messages[i].getSubject());
      System.out.println("Sent Date : " + messages[i].getSentDate());
      System.out.println("Type : " + messages[i].getContentType());
      if (messages[i].getContentType().contains("text")) {
        String o = messages[i].getContent().toString();
        System.out.println("text : " + o);
      } else if (messages[i].getContentType().contains("multipart")) {
        String o = ((MimeMultipart) messages[i].getContent()).getBodyPart(0).getContent().toString();
        System.out.println("mime : " + o);
      }
      System.out.println();
    }

    inbox.close(true);
    store.close();
  }
}

Vielleicht solltest Du Deinen Code dahingehend mal anpassen... und verwende bitte nicht Java 11.
 
Eine einzige Frage bleibt mir bestehen.
Bei der Methode checkEmail wird alles wichtige über die Email ausgegeben.
Nur das komische ist das bei message.getContent() javax.mail.internet.MimeMultipart@(ZAHLEN) ausgegeben wird.
Sollte bei message.getContent() nicht eigentlich der Inhalt der Email ausgegeben werden?
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben