使用Java在Gmail帐户上发送电子邮件

问题描述:

我知道这个问题以前曾被问过,但我认为这是2-3年之前的事情,此后情况发生了变化.现在,所有代码示例均无法正常工作.我正在Java 1.6中尝试以下代码:

I know this question is asked before but I think it was 2-3 years before and things have changed since then. None of the code samples is working now. I am trying the following code in Java 1.6:

Properties props = new Properties();
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.gmail.com");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.debug", "true");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("uname","password");
    }
});
session.setDebug(true);
Transport transport = session.getTransport();
InternetAddress addressFrom = new InternetAddress("abc@gmail.com");
MimeMessage message = new MimeMessage(session);
message.setSender(addressFrom);

for (int j = 0; j < 20; j++) {
    message.setSubject("Testing javamail plain"+Math.random());
    message.setContent("This is a test", "text/plain");
    String sendTo [] = {"abc@gmail.com"};
    if (sendTo != null) {
        InternetAddress[] addressTo = new InternetAddress[sendTo.length];
        for (int i = 0; i < sendTo.length; i++) {
            addressTo[i] = new InternetAddress(sendTo[i]);
        }
        message.setRecipients(Message.RecipientType.TO, addressTo);
    }
    transport.connect();
    Transport.send(message);
    transport.close();
    System.out.println("DONE");
}

并引发此异常:

org.apache.cxf.interceptor.Fault: javax.mail.NoSuchProviderException: Unable to locate provider for protocol: smtp
org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:155)
org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:121)
org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:164)
org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:91)
org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
java.util.concurrent.FutureTask.run(FutureTask.java:138)
org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:206)
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:218)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:161)
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:114)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:184)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:112)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:163)

我将tomcat用作网络服务器,并将cxf framefork用于网络服务.非常感谢您的帮助.

I am using tomcat as webserver and cxf framefork for webservices. Any help is much appreciated.

我假定您在类路径中有java.mail jar文件,而cxf支持jar文件.实际上,CXF使用Apache Geronimo Javamail/激活实现,因此,现在您的应用程序类路径中将有两个不同版本的Sun的Javamail库.当您的应用程序尝试发送电子邮件时,Java对应该使用的库版本感到困惑被使用,跌倒了.因此,解决方案可能是删除javamail jar文件或排除pom文件中的geronimo javamail,如:

I assume that you have java.mail jar file in your class path and cxf supporting jar files. Actually CXF makes use of Apache Geronimo Javamail/activation implementations, so now you will have two different versions of Sun's Javamail libraries in your application classpath, When your application tries to send an email, Java gets confused as to which version of the library it should be using, and falls over. So the solution might be either removing the javamail jar file or to exclude the geronimo javamail in the pom file like :

<exclusions>          
     <exclusion>               
         <groupId>org.apache.geronimo.specs</groupId>  
         <artifactId>geronimo-javamail_1.4_spec</artifactId>    
     </exclusion>
     <exclusion>  
          <groupId>org.apache.geronimo.specs</groupId>   
          <artifactId>geronimo-activation_1.1_spec</artifactId> 
     </exclusion>  

希望这对您有所帮助.