在 AWS 中的 Resin 3.1 上使用带有 SSL 的 Google 电子邮件服务

Posted

技术标签:

【中文标题】在 AWS 中的 Resin 3.1 上使用带有 SSL 的 Google 电子邮件服务【英文标题】:Using Google email service with SSL on Resin 3.1 in AWS 【发布时间】:2016-07-14 09:18:18 【问题描述】:

有史以来第一个问题。

我寻求帮助配置 java 和树脂以允许我从我的应用程序中打开 https URL 连接。 Resin 文档没有说,我认为我在 Java 中做的是正确的事情,但我遇到了“java.lang.NoClassDefFoundError:无法初始化类 sun.net.www.protocol.https.DelegateHttpsUrlConnection” .我希望修复是配置文件中的单行或缺少 jar...但是哪一个??

更多细节:

甲骨文Linux JDK 1.7 Resin 3.1(是的,它很旧) Google mail api v1(见下面的maven依赖)

我已经实现了一个 GmailSender 类,它可以从我的应用程序中发送电子邮件:

httpTransport = GoogleNetHttpTransport.newTrustedTransport();
...

private Credential authorizeServiceAccount() throws IOException, GeneralSecurityException 
        Credential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(serviceAccountId)
                .setServiceAccountPrivateKeyFromP12File(new File(privateKeyFileName))
                .setServiceAccountScopes(SCOPES)
                .setServiceAccountUser(serviceAccountUser)
                .build();
        return credential;


Gmail getGmailService() throws IOException, GeneralSecurityException 
    Credential credential = authorizeServiceAccount();
    return new Gmail.Builder(httpTransport, JSON_FACTORY, credential)
            .setApplicationName(applicationName)
            .build();


public void send(SimpleMailMessage simpleMailMessage) throws MailException 
    Message m;
    try 
        MimeMessage mm = asMimeMessage(simpleMailMessage);
        m = asMessage(mm);
     catch (IOException e) 
        throw new MailPreparationException("Unable to create email", e);
     catch (MessagingException e) 
        throw new MailPreparationException("Unable to create email", e);
    

    try 
        Gmail gmail = getGmailService();
        m = gmail.users().messages().send("me", m).execute();
     catch (IOException e) 
        throw new MailSendException("Unable to send mail", e);
     catch (GeneralSecurityException e) 
        throw new MailSendException("Could not send email", e);
     catch (Throwable t) 
        throw new MailSendException("Unexpected failure sending email", t);
    
    String id = m.getId();
    //System.out.println("Mail sent. Id is: " + id);

还有 Maven 配置:

    <dependency>
        <groupId>com.google.apis</groupId>
        <artifactId>google-api-services-gmail</artifactId>
        <version>v1-rev35-1.21.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client-jetty</artifactId>
        <version>1.21.0</version>
    </dependency>

还有一个例外——除了类定义问题之外,看起来大部分都很好:

20160326-15:15:54.481org.springframework.mail.MailSendException; 嵌套异常 (0) 是:20160326-15:15:54.481 由: java.lang.NoClassDefFoundError:无法初始化类 sun.net.www.protocol.https.DelegateHttpsURLConnection 20160326-15:15:54.481 在 sun.net.www.protocol.https.HttpsURLConnectionImpl.(HttpsURLConnectionImpl.java:86) 20160326-15:15:54.481 在 sun.net.www.protocol.https.Handler.openConnection(Handler.java:62) 20160326-15:15:54.481 在 sun.net.www.protocol.https.Handler.openConnection(Handler.java:57) 20160326-15:15:54.481 在 java.net.URL.openConnection(URL.java:971) 20160326-15:15:54.481 在 com.google.api.client.http.javanet.DefaultConnectionFactory.openConnection(DefaultConnectionFactory.java:31) 20160326-15:15:54.481 在 com.google.api.client.http.javanet.NetHttpTransport.buildRequest(NetHttpTransport.java:136) 20160326-15:15:54.481 在 com.google.api.client.http.javanet.NetHttpTransport.buildRequest(NetHttpTransport.java:62) 20160326-15:15:54.481 在 com.google.api.client.http.HttpRequest.execute(HttpRequest.java:863) 20160326-15:15:54.481 在 com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:283) 20160326-15:15:54.481 在 com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307) 20160326-15:15:54.481 在 com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384) 20160326-15:15:54.481 在 com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489) 20160326-15:15:54.481 在 com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217) 20160326-15:15:54.481 在 com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859) 20160326-15:15:54.481 在 com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419) 20160326-15:15:54.481 在 com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352) 20160326-15:15:54.481 在 com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469) 20160326-15:15:54.481 在 MyPackage.GmailSender.send(GmailSender.java:155)

我已经尝试在我的树脂启动脚本中设置协议:

args="-jar $RESIN_HOME/lib/resin.jar -server-root $SERVER_ROOT -conf $config -server $SERVER_NAME"
#args="-Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1 -jar $RESIN_HOME/lib/resin.jar -server-root $SERVER_ROOT -conf $config -server $SERVER_NAME"

但这种变化似乎没有影响。我错过了什么??

谢谢!!

【问题讨论】:

【参考方案1】:

另一种使用 java 发送电子邮件的方式

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendEmailUsingGMailSMTP 
   public static void main(String[] args) 
      // Recipient's email ID needs to be mentioned.
      String to = "reciverEmail@gmail.com";//change accordingly

      // Sender's email ID needs to be mentioned
      String from = "testemail@gmail.com";//change accordingly
      final String username = "testemail";//change accordingly
      final String password = "yourPassword";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "smtp.gmail.com";

      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "587");

      // Get the Session object.
      Session session = Session.getInstance(props,
      new javax.mail.Authenticator() 
         protected PasswordAuthentication getPasswordAuthentication() 
            return new PasswordAuthentication(username, password);
         
      );

      try 
         // Create a default MimeMessage object.
         Message message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.setRecipients(Message.RecipientType.TO,
         InternetAddress.parse(to));

         // Set Subject: header field
         message.setSubject("Testing Subject");

         // Now set the actual message
         message.setText("Hello, this is sample for to check send "
            + "email using JavaMailAPI ");

         // Send message
         Transport.send(message);

         System.out.println("Sent message successfully....");

       catch (MessagingException e) 
            throw new RuntimeException(e);
      
   

如果您收到 javax.mail.AuthenticationFailedException 请转到gmail设置https://www.google.com/settings/security/lesssecureapps

【讨论】:

我正在放弃这种方法,转而使用更快、更安全的 Google Mail API。我的 Junit 测试运行良好 - 它们只是不在 Web 容器中运行。【参考方案2】:

看起来 NoClassDefFound 错误是由于未正确初始化记录器而在 URL 连接类中引发 ExceptionInInitializer。

Resin 3.1.5 中对日志记录进行了大修,我查看了 Resin 的发行说明,但没有看到此问题的报告。但以防万一,我升级到 Resin 3.1.15 并且瞧 - 问题消失了。

底线——resin 3.1.5 日志记录中有一个讨厌的错误,它会破坏 java 7 https URL 连接。谁知道……

【讨论】:

以上是关于在 AWS 中的 Resin 3.1 上使用带有 SSL 的 Google 电子邮件服务的主要内容,如果未能解决你的问题,请参考以下文章

带有负载均衡器的 AWS Elastic Beanstalk Linux 托管实例上的 ASP.NET Core 3.1 - HTTPS

是否可以将错误消息重定向到 Resin 4 中的浏览器窗口?

如何在 AWS 上运行带有自动回归测试套件的分析器

在 AWS 上部署带有 H2 数据库的 Spring Boot 应用程序

AWS上带有nginx和gunicorn的Flask应用程序[重复]

为啥在 Rails 3.1 上不再使用带有作用域的合并方法?