JavaMail u IMAP - NullPointerException beim Mailcontent

Kumaro

Mitglied
Hi,
ich habe folgendes Problem:
Ich will mittles der JavaMail API meine Mails via IMAP von meinem MailServer abrufen.
Der Verbindungsaufbau klappt und es werden auch die Mails aus der INBOX geladen.

Java:
public class MailServiceImpl extends RemoteServiceServlet implements MailService, Serializable{

    String user;
    String password;
    ArrayList<String> responseJsonList;

    public MailServiceImpl() {}


        public ArrayList<String> getMails(String user, String pass){
    
            String mailDomain = "@domain.xy";
        
            //haengt hinter den User noch die mailDomain damit der Anmeldename komplett ist
            this.user = user + mailDomain;
            this.password = pass;
        
            System.out.println("User: "+ this.user + "/ Pasw: " + this.password);
        
            String host = "mail.domain.xy";
        
            try{
                //System Properties holen
                Properties properties = System.getProperties();
                //Mail-Server properties: Session verlangt die Informationen über Host, User, Passwd etc.
                properties.put("mail.imap.host", host);
                properties.put("mail.imap.auth", "true");
            
                //Initialisierung der Auth-Klasse zur Mail-Account-Authentisierung; in Session benutzt
                Authenticator auth = new MailAuthenticator();
            
                //Verbindung zum MailServer
                Session mailSession = Session.getDefaultInstance(properties, auth);
                //Gibt in der Console eine Debug-Meldung zum Verlauf aus
                mailSession.setDebug(false);
            
                Folder mailFolder = openIMAPInboxReadOnly(mailSession);
            
                Message messages[] = mailFolder.getMessages();
            
                System.out.println("Anzahl der Nachrichten: " + messages.length);
            
                showMails(messages);

responseJsonList = new ArrayList<String>();
            
                for(int i=0; i < messages.length; i++ ){
                    MessageResponseObject messageResp = new MessageResponseObject();
                    messageResp.setDate(messages[i].getSentDate().toString());
                    messageResp.setFrom(messages[i].getFrom().toString());
                    messageResp.setSubject(messages[i].getSubject());
                    messageResp.setContent(messages[i].getContent().toString());
                    String jsonString = createJsonString(messageResp);
                    System.out.println("TEST:" + jsonString);
                
                    responseJsonList.add(jsonString);
                    System.out.println("Anzahl an NAchrichten im Array: " + responseJsonList.size());
                }
            
                closeInbox(mailFolder);
            
            
            
            }catch(Exception err){
            
                System.out.println("Die Anmeldung ist fehlgeschlagen!");
                System.out.println(err);
            }
        
        
            return responseJsonList;
    
        
        }


Java:
/**
     * Create a JSON String for the network transport
     * @param messageResp
     * @return
     */
    private String createJsonString(MessageResponseObject messageResp){
    
        Gson gson = new Gson();
        return gson.toJson(messageResp, MessageResponseObject.class);
    }
    
    
    
    /**
     * Erzeugt das Authenticator-Objekt zur Anmeldung am MailAccount
     * @author Kumaro
     *
     */
    private class MailAuthenticator extends javax.mail.Authenticator {
        
        public PasswordAuthentication getPasswordAuthentication(){
                //System.out.println("User: "+ user + "/ Pasw: " + password);
            return new PasswordAuthentication(user, password);
            
        }
    }



    /**
     * Erzeugt das Store-Objekt über IMAP und legt die EMails dann im MailFolder ab und gibt dieses Objekt zurück
     * @param mailSession
     * @return mailFolder
     * @throws MessagingException
     */
    private Folder openIMAPInboxReadOnly(Session mailSession) throws MessagingException{
        //Store dient zum Ablegen der Nachrichten
        Store mailStore = mailSession.getStore("imap");
        mailStore.connect();
    
        //Folder ist ein Ordner-Objekt für Mails
        Folder mailFolder = mailStore.getFolder("INBOX");
        mailFolder.open(Folder.READ_ONLY);
    
        return mailFolder;
    }


    /**
     * Beendet die Verbindung zum InboxOrdner
     * @param mailFolder
     * @throws MessagingException
     */
    private void closeInbox(Folder mailFolder) throws MessagingException{
        mailFolder.close(true);
        mailFolder.getStore().close();
    }


    /**
     * Gibt die Mails aus
     * @param message
     * @throws MessagingException
     * @throws IOException
     */
    private void showMails(Message[] message) throws MessagingException, IOException{
    
        for(int i=0;i<message.length;i++){
        
            System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!" + message.length);
        
            Message m = message[i];
       
            System.out.println( "-----------------------\nNachricht: " + i );
            System.out.println( "Von: " + Arrays.toString(m.getFrom()) );
            System.out.println( "Betreff: " + m.getSubject() );
            System.out.println( "Gesendet am: " + m.getSentDate() );
            System.out.println( "Content: " + m.getContent() );
                  
         }
    
    }

Ich kann das Datum, den Betreff und den Sender aus dem Message-Objekt auslesen, sobald ich aber auf den CONTENT des Message-Objekts zugreifen möchte z.B. hier:

Java:
  messageResp.setContent(messages[i].getContent().toString());
oder
Java:
   System.out.println( "Content: " + m.getContent() );

bekomm ich eine NULLPointerException und ich kann mir leider nicht erklären warum :(
Was mach ich falsch???
Im Grunde mach ich alles so wie es im Netz überall zu finden ist...

Ich hoffe ihr könnt mir helfen :).

Ergänzende Frage:
Ist der Aufbau der Mailverbindung eigentlich irgendwie gesichert oder wird da der Benutzername u Passwort unverschlüsselt übertragen?
 
Zuletzt bearbeitet von einem Moderator:

Improof

Erfahrenes Mitglied
Hi Kumaro,

geh doch mal mit Debugging durch deinen Code und überprüfe in Eclipse deine Variablen. Ist das Message-Objekt null oder die Content Variable im Message-Objekt?
Das komische ist nämlich:
Java:
 Message m = message[i];
     
            System.out.println( "-----------------------\nNachricht: " + i );
            System.out.println( "Von: " + Arrays.toString(m.getFrom()) );
            System.out.println( "Betreff: " + m.getSubject() );
            System.out.println( "Gesendet am: " + m.getSentDate() );
            System.out.println( "Content: " + m.getContent() );

Wenn du, wie von dir beschrieben, erst in der letzten Zeile beim Abfragen des Contents die Exception bekommst, kann irgendwas nicht ganz stimmen. Wenn das Message-Objekt null wäre, dann müsste ja schon "m.getFrom()" die Exception werfen...

Bei der anderen Codezeile...
Code:
messageResp.setContent(messages[i].getContent().toString());
...kann ich mir das eher vorstellen, denn wenn der Content null ist, läuft ".toString()" ja bekanntlicherweise ins Leere. Nur mal so am Rande: Sind deine Test-Mails mit Inhalt oder sind die leer? Manchmal sind die es dümmsten Fehler, auf die man nicht kommt, deswegen frag ich :D

Gruß
Daniel
 

Kumaro

Mitglied
Hi Daniel :),

also es ist scheinbar nur die Content Variable leer. Ich kann mir den Betreff, das Datum usw. ausgeben lassen. Deswegen wundert mich das ja auch so ^^.
Ja die Testmail hat als Inhalt:

"Hallo,
das ist eine TestEmail.
Viele Grüße"

Wenn das ganze Objekt null wäre würde das irgendwo vielleicht sinn machen... aber das nur der content leer ist... kann ich mir leider nicht erklären :(
 

Improof

Erfahrenes Mitglied
Hi Kumaro,

scheint mir auch irgendwie seltsam zu sein :/
Ich hab mal google bisschen angeschmissen und bin auf ein interessantes JavaMail Beispiel gestoßen, der baut die Verbindung auch etwas anders auf (auch wenn er die gleichen Objekte verwendet). Siehs dir einfach mal an, dann weißt du, was ich damit mein.
Link: http://www.compiletimeerror.com/2013/06/reading-email-using-javamail-api-example.html#.VGrodPmG__U

Weiter unten in dem Beitrag ist auch der komplette Code. Würds einfach mal so eins zu eins testen ;)

Gruß
Daniel
 

Kumaro

Mitglied
Danke für den link. Ich hab das mal ausprobiert...

Java:
Properties props = new Properties();
            props.setProperty("mail.store.protocol", "imaps");
         
            try {
                Authenticator auth = new MailAuthenticator();
                Session session = Session.getInstance(props, auth);
                Store store = session.getStore();
                store.connect(host,user,password);
                Folder inbox = store.getFolder("INBOX");
                inbox.open(Folder.READ_ONLY);
             
                Message msg = inbox.getMessage(1);
             
                Address[] in = msg.getFrom();
             
                for (Address address : in) {
                    System.out.println("FROM:" + address.toString());
                }
                Multipart mp = (Multipart) msg.getContent();
                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 e) {
                e.printStackTrace();
            }
            return responseJsonList;
}


    private class MailAuthenticator extends javax.mail.Authenticator {
          
        public PasswordAuthentication getPasswordAuthentication(){
                //System.out.println("User: "+ user + "/ Pasw: " + password);
            return new PasswordAuthentication(user, password);
              
        }
    }

Und da erhalte ich jetzt:


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 (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:670)
at javax.mail.Service.connect(Service.java:248)
at javax.mail.Service.connect(Service.java:91)
at webmail.server.MailServiceImpl.getMails(MailServiceImpl.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:561)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:265)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:305)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:491)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
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:1439)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:878)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:814)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
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.iap.Protocol.<init>(Protocol.java:116)
at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:115)
at com.sun.mail.imap.IMAPStore.newIMAPProtocol(IMAPStore.java:685)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:636)
... 49 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:1421)
... 63 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)
... 69 more




Ich kanns mir nicht erklären.. :'(
....

Jemand eine Idee was ich übersehe??
 
Zuletzt bearbeitet:

Improof

Erfahrenes Mitglied
Hey Kumaro,

die Exception ist mir neu, noch nie gesehen, aber laut google hat das wohl etwas mit SSL und Zertifikaten zu tun (wenn man sich den StackTrace genauer ansieht, stehen da ja auch Begriffe wie SSL und Certificate). Ich hab grad nur mal nach "java PKIX path building failed" gesucht, hat wohl nichts an sich mit javaMail zu tun, sondern ist n allgemeiner SSL Fehler. Allerdings hab ich damit noch nie was gemacht, also hoff ich nur, dass dich des vielleicht auf die richtige Spur bringen könnte :)

Gruß
Daniel