# [GWT] JavaMail kommt nicht an



## N4pst3r (16. Mai 2012)

Hallo liebe Community,
Ich hab ein Problem mit der JavaMail API wenn ich diese per GWT verwende.
Ich habe schon eine Anwendung mit der JavaMail implementiert und möchte das ganze nun zur Übung über GWT realisieren. Das Programm läuft stabil (RPC und alles) aber

die verschickte E-Mail kommt nicht an... Ich bekomme keine Fehlermeldung und nichts. Die Routine läuft problemlos durch, nur empfängt der Empfänger die Mail nicht ???:L
Hoffentlich kann mir hier wer helfen - Google liefert keine Antworten
Hier mal der relevante Code falls es hilft:

Die serverseitige Servicemethode, die beim Abschicken aufgerufen wird:

```
public class GWTServiceImpl extends RemoteServiceServlet implements GWTService {
	
	public String sendEmail() {
		try {
			GWTMailer eMail = new GWTMailer( "Hostname", (int) Port, "Benutzername", "Passwort" );
			eMail.setEmailRecipient( "<empfänger@email.de>" );
			eMail.setEmailSender( "<absender@email.de>" );
			eMail.setEmailSubject( "<Betreff>" );
			eMail.setEmailText( "<Nachrichtentext>" );
			eMail.send();
			return "E-Mail wurde erfolgreich an " + eMail.getEmailRecipient() + " verschickt";
		}
		catch( Exception e ) {
			return "E-Mail wurde nicht verschickt!" + e.getMessage();
		}
	}
}
```
Die Methode setzt die benötigten Variablen in der GWTMailer-Klasse und generiert daraus eine E-Mail.

hier die GWTMailer-Klasse (ebenfalls serverseitig):

```
public class GWTMailer {
	
	private String smtpHost;
	private int smtpPort;
	private String smtpUser;
	private String smtpPassword;
	private String emailSender;
	private String emailRecipient;
	private String emailSubject;
	private String emailText;
	
	public GWTMailer( String host, int port, String user, String password ) {
		smtpHost = host;
		smtpPort = port;
		smtpUser = user;
		smtpPassword = password;
	}
	
	public void setEmailSender( String sender ) {
		emailSender = sender;
	}
	
	public String getEmailRecipient() {
		return emailRecipient;
	}
	
	public void setEmailRecipient( String recipient ) {
		emailRecipient = recipient;
	}
	
	public void setEmailSubject( String subject ) {
		emailSubject = subject;
	}
	
	public void setEmailText( String text ) {
		emailText = text;
	}
	
	public void send() {
		Properties props = new Properties();
		props.put( "mail.smtp.host", smtpHost );
		props.put( "mail.smtp.auth", "true" );
		props.put( "mail.smtp.port", smtpPort );
		Session ses = Session.getDefaultInstance( props, new Login(smtpUser, smtpPassword) );
		Message msg = new MimeMessage( ses );
		try {
			msg.setFrom( new InternetAddress( emailSender ) );
			msg.setRecipient( Message.RecipientType.TO, new InternetAddress(emailRecipient) );
			msg.setSubject( emailSubject );
			msg.setText( emailText );
			Transport.send( msg );
		}
		catch( Exception e ) {
			e.printStackTrace( System.err );
		}
	}
}
```

Die Servicemethode wird wie gewohnt über einen AsyncCallback vom client aufgerufen:

```
btnSubmit.addClickHandler( new ClickHandler() {

	public void onClick( ClickEvent event ) {
		getService().sendEmail( new AsyncCallback() {

			public void onFailure( Throwable caught ) {
				Window.alert( "Failed" );
			}

			public void onSuccess( Object result ) {
				Window.alert( "Success : " + result.toString() );
			}
		});
	}
});
```
Es wird dann die onSuccess-Methode ausgeführt (d.h. Serverresponse) aber
EINE E-MAIL KOMMT NIE AN! :autsch:

Ich weiß nicht ob hier jemand über das Google Web Toolkit bescheid weiß oder ob ich hier im richtigen Unterforum poste aber hoffentlich kann mir jemand helfen 

MFG N43


----------



## javamailer (16. Mai 2012)

E-Mails mit JavaMail versenden @ tutorials.de: Tutorials, Forum & Hilfe

versuche mal anstatt dem static call Transport.send(Message) dir vorher ein Transport-objekt zu holen und dann darauf sendMessage(Message, Address) zu callen ...

ist leider das problem bei fast allen "tutorials" und "code-snippets" die man zu JavaMail und POP3 via SSL/TLS findet ...

grund : static Transport.send(Message) verwendet seine eigenen werte ... dabei ist es egal was du in deine session reinpackst ... da durch die API NICHT garantiert wird das alle informationen aus der Session in der Message und damit in Transport landen ...


----------



## N4pst3r (16. Mai 2012)

Kein schlechter Gedanke. Für meine Desktop-JavaMail habe ich auch System.getProperties() statt new Properties() verwendet.
Leider muss ich sagen das das Problem weiterhin besteht. Ich habe erst die Transport-Klasse instanziiert und dann den gesamten Code mit dem von tutorials.de ausgetauscht - Alles das gleiche
Die EMails werden laut Programm rausgeschickt, kommen aber nie an ;( echt zum heulen


----------



## darekkay (16. Mai 2012)

Eventuell würde ich das Exception-Handling überarbeiten. Der RPC-Call wird in deinem Beispiel niemals fehlschlagen (außer der GWTMailer-Konstruktor schmeißt eine Exception). Alles, was beim tatsächlichen Verschicken fehlschlagen kann, fängst du direkt in send() ab. Sollte da was kaputt gehen, wird der Client das niemals erfahren. Wenn das nicht hilft, dann müsste man den Code direkt debuggen, z.B. mit nem Breakpoint in Transport.send(msg).

Kenn mich mit der Mail-API nicht aus, aber vielleicht muss man irgendwo noch Einstellungen vornehmen, damit es überhaupt funktioniert? Sperrt dein Tomcat/Jetty die Verbindung vielleicht? Ports?


----------



## N4pst3r (21. Mai 2012)

Hi
hab das Problem gelöst:
Weiß nicht genau aber anscheinend gibts ein Problem mit dem Provider.
Von anderen E-Mail-Konten aus kann problemlos gesendet werden...

Naja am falschen Ort den Fehler gesucht


----------



## streeter (3. Jul 2012)

Hallo,

ich habe ein ähnliches Problem mit GWT. Muss dazu sagen, dass ich noch sehr neu im Umgang mit GWT bin und gerade erst meine erste Anwendung mit RPC-Funktion geschrieben habe. Vielleicht ist das sogar schon das Problem? Der Email-Versand aus einer Test-Klasse heraus funktioniert problemlos. Rufe ich jedoch die selbe Methode aus GWT heraus auf, bekomme ich eine AccessControlException. Hier der Code meines Handlers:


```
public class SendButtonHandler implements ClickHandler
{
	//fields
	TextItem subjectItem;
	TextItem receiverItem;
	RichTextEditor emailEditor;

	private EmailSendServiceAsync sendEmailSvc = GWT.create(EmailSendService.class);
	
	
	//constructor
	public SendButtonHandler(TextItem subjectItem, TextItem receiverItem, RichTextEditor emailEditor)
	{
		this.subjectItem = subjectItem;
		this.receiverItem = receiverItem;
		this.emailEditor = emailEditor;
	}
	

	@Override
	public void onClick(ClickEvent event)
	{
		System.out.println("send button clicked");
		try
		{
			if(sendEmailSvc == null)
			{
				sendEmailSvc = GWT.create(EmailSendService.class);
			}
			final AsyncCallback<int[]> callback = new AsyncCallback<int[]>()
			{
				public void onFailure(Throwable caught) 
				{
			       System.out.println("failure");
			    }

			    public void onSuccess(int[] result) 
			    {
			    	System.out.println("success");
			    }
			};

//			AccessController.doPrivileged(new PrivilegedAction<Object>() {
//
//				@Override
//				public Object run()
//				{
//					try
//					{
//						sendEmailSvc.postMail(<empfänger-addresse>, subjectItem.getValue().toString(), emailEditor.getValue(), <sender-addresse>, callback);
//					} catch (Exception e)
//					{
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//					return null;
//				}
//				
//			});
			//receiverItem.getValue().toString()
			sendEmailSvc.postMail(<sender-addresse>, subjectItem.getValue().toString(), emailEditor.getValue(), <empfänger-addresse>, callback);
//			sendEmailSvc.postMail(<sender-addresse>, "test", "von java", <empfänger-addresse>, callback);
		} 
		catch (Exception e)
		{
			System.err.println("Sending failed");
			e.printStackTrace();
		}
	}
}
```

Meine Service-Klasse:


```
@RemoteServiceRelativePath("emailSend")
public interface EmailSendService extends RemoteService
{
	public int[] postMail(String recipient, String subject, String message, String from ) throws Exception;
//	public EmailDummy EmailDummy(EmailDummy ed);
}
```

Die Async-Klasse:


```
public interface EmailSendServiceAsync
{
	public void postMail(String recipient, String subject, String message, String from, AsyncCallback<int []> callback) throws Exception;
//	public void EmailDummy(EmailDummy d, AsyncCallback< EmailDummy> callback);
}
```

Und schließlich die Implementierung:


```
public class EmailSendServiceImpl extends RemoteServiceServlet implements EmailSendService, IsSerializable
{

	/**
	 * 
	 */
	MailAuthenticator auth = new MailAuthenticator(<username>, <passwort>);
	
	
	//constructor
	public EmailSendServiceImpl()
	{
		
	}

	@Override
	/**
	 * sends an email from a sender to a receiver
	 */
	public int[] postMail( final String recipient, final String subject, final String message, final String from ) 
	{
			System.out.println("sending email .....");
//			AccessController.doPrivileged(new PrivilegedAction<Object>() {
//	            public Object run() {
//	                // privileged code goes here, for example:
//	                System.loadLibrary("awt");
	                try
	                {
		                Properties props = new Properties();
		                props.put("mail.smtp.host", "smtp.googlemail.com");
		                props.put("mail.transport.protocol","smtp"); 
		                props.put("mail.smtp.port", "465");
		                props.put("mail.smtp.starttls.enable","true");
		                props.put("mail.smtp.auth", "true");
		                props.put("mail.debug","true"); 
		                Session session = Session.getDefaultInstance(props, auth);
		                Message msg = new MimeMessage( session );
		                InternetAddress addressFrom = new InternetAddress( from );
		                msg.setFrom( addressFrom );
		                InternetAddress addressTo = new InternetAddress( recipient );
		                msg.setRecipient( Message.RecipientType.TO, addressTo );
		                msg.setSubject( subject );
		                msg.setContent( message, "text/plain" );
		                msg.saveChanges(); 
		                Transport.send( msg );
	                	
//	                	Email email = new SimpleEmail();
//	                	email.setHostName("smtp.googlemail.com");
//	                	email.setSmtpPort(465);
//	                	email.setAuthenticator(new DefaultAuthenticator(<username>, <passwort>));
//	                	email.setSSL(true);
//	                	email.setFrom(<sender-addresse>);
//	                	email.setSubject("test");
//	                	email.setMsg("test");
//	                	email.addTo(<empfänger-addresse>);
//	                	email.send();

	                }
	                catch(MessagingException me)
	                {
	                	System.err.println("error sending mail");
	                	me.printStackTrace();
	                }
	                catch(Exception e)
	                {
	                	System.err.println("an error occured");
	                	e.printStackTrace();
	                }
//	                return null; // nothing to return
//	            }
//	        });
			System.out.println("..... email sent");
		int intArray[] = {1,2,3};
		return intArray;
	}

//	@Override
//	public EmailDummy EmailDummy(EmailDummy ed)
//	{
//		return ed;
//	}

}
```

Ich spiele jetzt schon seit drei Tagen an dem Problem herum. 
Wie an den auskommentierten Zeilen zu sehen, habe ich schon viel versucht:

Verwenden von apache-commons anstatt der java-mail-api
Implementierung einer Dummy-Klasse, um eventuell durch die Google-App-Engine gesperrte Klassen des javax.mail-Packages in die Whiteliste durch Serialisierung aufzunehmen
Verwenden eines AccessControlers mit doPrivileged

Das Ergebnis ist jedoch immer das Gleiche:


```
send button clicked
sending email .....
Loading META-INF/javamail.providers from jar:file:/D:/workspace/EmailTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.7.0.jar!/META-INF/javamail.providers
DEBUG: loading new provider protocol=gm, className=com.google.appengine.api.mail.stdimpl.GMTransport, vendor=null, version=null
Loading META-INF/javamail.providers from jar:file:/D:/workspace/EmailTest/war/WEB-INF/lib/imap.jar!/META-INF/javamail.providers
DEBUG: loading new provider protocol=imap, className=com.sun.mail.imap.IMAPStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=imaps, className=com.sun.mail.imap.IMAPSSLStore, vendor=Sun Microsystems, Inc, version=null
Loading META-INF/javamail.providers from jar:file:/D:/workspace/EmailTest/war/WEB-INF/lib/pop3.jar!/META-INF/javamail.providers
DEBUG: loading new provider protocol=pop3, className=com.sun.mail.pop3.POP3Store, vendor=Sun Microsy stems, Inc, version=null
DEBUG: loading new provider protocol=pop3s, className=com.sun.mail.pop3.POP3SSLStore, vendor=Sun Microsystems, Inc, version=null
Loading META-INF/javamail.providers from jar:file:/D:/workspace/EmailTest/war/WEB-INF/lib/smtp.jar!/META-INF/javamail.providers
DEBUG: loading new provider protocol=smtp, className=com.sun.mail.smtp.SMTPTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtps, className=com.sun.mail.smtp.SMTPSSLTransport, vendor=Sun Microsystems, Inc, version=null
Loading javamail.default.providers from jar:file:/D:/workspace/EmailTest/war/WEB-INF/lib/mail.jar!/META-INF/javamail.default.providers
DEBUG: loading new provider protocol=imap, className=com.sun.mail.imap.IMAPStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=imaps, className=com.sun.mail.imap.IMAPSSLStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtp, className=com.sun.mail.smtp.SMTPTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtps, className=com.sun.mail.smtp.SMTPSSLTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=pop3, className=com.sun.mail.pop3.POP3Store, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=pop3s, className=com.sun.mail.pop3.POP3SSLStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: getProvider() returning provider protocol=smtp; type=javax.mail.Provider$Type@c70cb4c; class=com.sun.mail.smtp.SMTPTransport; vendor=Sun Microsystems, Inc
DEBUG SMTP: useEhlo true, useAuth true
an error occured
java.security.AccessControlException: access denied (java.net.SocketPermission smtp.googlemail.com resolve)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
	at java.security.AccessController.checkPermission(AccessController.java:546)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:283)
	at java.lang.SecurityManager.checkConnect(SecurityManager.java:1031)
	at java.net.InetAddress.getAllByName0(InetAddress.java:1145)
	at java.net.InetAddress.getAllByName(InetAddress.java:1083)
	at java.net.InetAddress.getAllByName(InetAddress.java:1019)
	at java.net.InetAddress.getByName(InetAddress.java:969)
	at javax.mail.Service.connect(Service.java:257)
	at javax.mail.Service.connect(Service.java:91)
	at javax.mail.Service.connect(Service.java:76)
	at javax.mail.Transport.send(Transport.java:94)
	at javax.mail.Transport.send(Transport.java:48)
	at de.xsolut.mstrasser.training.email.server.EmailSendServiceImpl.postMail(EmailSendServiceImpl.java:66)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
	at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
	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.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
	at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60)
	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.BackendServersFilter.doFilter(BackendServersFilter.java:97)
	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:94)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:370)
	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)
..... email sent
success
```

Ich weiß auch nicht, wieso der Callback "success" zurück gibt. Weil ich den Fehler in einer Exception auffange?
Würde mich jedenfalls sehr freuen, wenn mir jemand helfen könnte. Danke schonmal!


----------



## streeter (4. Jul 2012)

@N4pst3r: Hat es denn dann bei dir auch aus der Google App Engine funktioniert oder hast du es auf einem anderen App-Server (Tomcat?) laufen lassen?


----------



## N4pst3r (5. Jul 2012)

@streeter: Nein ich benutze einen glassfish_server_3.1.2 und den GAE-Server mag ich sowieso nicht  Aber wenn du die IDE Eclipse verwendest ist der GAE die beste Wahl


----------



## streeter (5. Jul 2012)

Danke für die Antwort. Ich habe es mittlerweile auf einen Tomcat deployed. Da funktioniert es problemlos. Es ist wirklich nur ein Problem der Google App Engine. Dort ist das javax.mail-Package einfach gesperrt :bahnhof:


----------



## N4pst3r (5. Jul 2012)

naja gut ich wollt mich gerade ranmachen und deinen code debuggen 
Aber JavaMail und WebServer scheinen nicht die besten Freunde zu sein


----------

