Java Google App Engine 不会通过 Mailgun SMTP 发送电子邮件
Java Google App Engine won't send email via Mailgun SMTP
我已经按照教程进行操作,并在端口 2525 上为入口和出口设置了 GCP 防火墙。运行 我机器上的本地代码成功发送了电子邮件,但是将项目部署到 App Engine标准(Java 运行时)不会引发错误,但也不会发送电子邮件。
我还有一个 GCP VM 实例也可以发送电子邮件。有谁知道是什么原因造成的?
依赖关系:
Dependencies
String email = "target@email.com";
String API_KEY = "KEY";
HttpResponse<JsonNode> req = Unirest.post("https://api.mailgun.net/v3/" + "my.custom.domain" + "/messages")
.basicAuth("api", API_KEY)
.field("from","Admin <admin@my.custom.domain>")
.field("to", email)
.field("subject","Welcome!")
.field("text", "testing")
.asJson();
req.getBody();
抛出:
Exception in thread "main" java.lang.ExceptionInInitializerError
at tech.incineratez.email.Main.main(Main.java:14)
Caused by: kong.unirest.UnirestException: It looks like you are using an
older version of Apache Http Client.
For security and performance reasons Unirest requires the most recent
version. Please upgrade.
at kong.unirest.Config.setDefaults(Config.java:109)
at kong.unirest.Config.<init>(Config.java:85)
at kong.unirest.Unirest.<clinit>(Unirest.java:30)
... 1 more
Caused by: java.lang.BootstrapMethodError: java.lang.IllegalAccessError:
no such constructor: kong.unirest.apache.ApacheAsyncClient.<init>
(Config)void/newInvokeSpecial
at kong.unirest.Config.setDefaults(Config.java:106)
... 3 more
Caused by: java.lang.IllegalAccessError: no such constructor:
kong.unirest.apache.ApacheAsyncClient.<init>(Config)void/newInvokeSpecial
at
java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:483)
... 4 more
Caused by: java.lang.NoClassDefFoundError:
org/apache/http/nio/reactor/ConnectingIOReactor
at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975)
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000)
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394)
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750)
at
java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477)
... 4 more
Caused by: java.lang.ClassNotFoundException: org.apache.http.nio.reactor.ConnectingIOReactor
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 10 more
工作代码如果 运行 单独在我的计算机上而不是在 Google 云平台上:
Properties props = System.getProperties();
props.put("mail.smtps.host", "smtp.mailgun.org");
props.put("mail.smtps.auth", "true");
props.put("mail.smtps.port", "2525");
Session session = Session.getInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("admin@my.custom.domain"));
InternetAddress[] addrs = InternetAddress.parse(email, false);
msg.setRecipients(Message.RecipientType.TO, addrs);
msg.setSubject("Welcome!");
msg.setText("Test");
msg.setSentDate(new Date());
SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
t.connect("smtp.mailgun.org", "postmaster@my.custom.domain", "KEY");
t.sendMessage(msg, msg.getAllRecipients());
System.out.println("Email sent" + t.getLastServerResponse());
t.close();
依赖关系:Dependencies2
在 Google 云平台上 运行 时上面的代码什么都不做。
我猜您是在谈论 this tutorial 配置通过 Compute Engine 发送邮件(这解释了为什么它在您的 VM 实例上运行良好)。
该教程适用于 Compute Engine,如果是 App Engine 标准应用程序,您可以选择使用 Mail API, however, since Google is no longer accepting quota increases API,建议使用第三方服务,例如作为 MailGun 或 SendGrid。
要将您的 App Engine 标准应用程序(需要 Java 运行 时间)与这些第三方服务连接,您需要在 "pom.xml" 上指定 "dependicies"文件并使用 API 键修改您的 "app.yaml":
env_variables:
EMAIL_API_KEY: key-from-third-party
Email API 密钥将由第三方服务提供,例如,在 MailGun 的情况下,他们的 documentation 指定如下:
When you sign up for an account, you are given an API key. You
authenticate to the Mailgun API by providing your API key in the
request. You can manage your API key in the “Security” tab under the
Account section of the Control Panel.
有关如何配置 App Engine 标准应用程序以连接这些第三方服务的分步说明,请参阅此 documentation。
编辑:
在你的情况下,你可能正在使用另一个依赖项(因此,依赖项错误)。创建代码时,您是否参考了 App Engine Java 8 文档示例或 Mailgun 示例?因为我注意到它们使用不同的依赖项,而且 App Engine 示例使用环境变量(根据您共享的代码片段,您没有使用)。
我的建议是遵循为 Google App Engine Standard Java 8 提供的示例。
这些是我在 App Engine 上成功启动和 运行ning 所采取的步骤:
1. 下载了 sample code。
2. 在 Mailgun 创建了一个帐户(简单帐户,未附加信用数据)。您将需要通过指定的电子邮件验证您的帐户。
3. 登录 MailGun 后,您将在左侧看到一个菜单,导航至“发送”>“概览”页面。
4. 在右边你会看到一个"Authorized Recipients"框,添加电子邮件或将收到电子邮件的人,他们也需要确认他们这边,所以为了测试,请尝试添加您可以访问的电子邮件。注意:如果您还没有 verified your domain.
,则需要执行此操作
5. 复制您的默认域名(或您已验证的域名)的值。
6.在同一个框里有一个菜单link到"Api Keys",点击它,复制[=89=下面的键](这也是你的私钥,所以放在哪里要小心)。
7. 前往下载的 GCP 示例,然后编辑文件 "/mailgun/src/main/webapp/WEB-INF/appengine-web.xml" 使用这些值(域和密钥)。
8. 如果您使用 Maven 运行 命令:
mvn appengine:run (if you want to test locally)
或
mvn appengine:deploy (if you want to deploy to App Engine)
注意: 其中一些步骤对您来说可能看起来很明显,但我已经以这种方式进行了解释,以便其他人也可以遵循。
我已经按照教程进行操作,并在端口 2525 上为入口和出口设置了 GCP 防火墙。运行 我机器上的本地代码成功发送了电子邮件,但是将项目部署到 App Engine标准(Java 运行时)不会引发错误,但也不会发送电子邮件。
我还有一个 GCP VM 实例也可以发送电子邮件。有谁知道是什么原因造成的?
依赖关系: Dependencies
String email = "target@email.com";
String API_KEY = "KEY";
HttpResponse<JsonNode> req = Unirest.post("https://api.mailgun.net/v3/" + "my.custom.domain" + "/messages")
.basicAuth("api", API_KEY)
.field("from","Admin <admin@my.custom.domain>")
.field("to", email)
.field("subject","Welcome!")
.field("text", "testing")
.asJson();
req.getBody();
抛出:
Exception in thread "main" java.lang.ExceptionInInitializerError
at tech.incineratez.email.Main.main(Main.java:14)
Caused by: kong.unirest.UnirestException: It looks like you are using an
older version of Apache Http Client.
For security and performance reasons Unirest requires the most recent
version. Please upgrade.
at kong.unirest.Config.setDefaults(Config.java:109)
at kong.unirest.Config.<init>(Config.java:85)
at kong.unirest.Unirest.<clinit>(Unirest.java:30)
... 1 more
Caused by: java.lang.BootstrapMethodError: java.lang.IllegalAccessError:
no such constructor: kong.unirest.apache.ApacheAsyncClient.<init>
(Config)void/newInvokeSpecial
at kong.unirest.Config.setDefaults(Config.java:106)
... 3 more
Caused by: java.lang.IllegalAccessError: no such constructor:
kong.unirest.apache.ApacheAsyncClient.<init>(Config)void/newInvokeSpecial
at
java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:483)
... 4 more
Caused by: java.lang.NoClassDefFoundError:
org/apache/http/nio/reactor/ConnectingIOReactor
at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975)
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000)
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394)
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750)
at
java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477)
... 4 more
Caused by: java.lang.ClassNotFoundException: org.apache.http.nio.reactor.ConnectingIOReactor
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 10 more
工作代码如果 运行 单独在我的计算机上而不是在 Google 云平台上:
Properties props = System.getProperties();
props.put("mail.smtps.host", "smtp.mailgun.org");
props.put("mail.smtps.auth", "true");
props.put("mail.smtps.port", "2525");
Session session = Session.getInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("admin@my.custom.domain"));
InternetAddress[] addrs = InternetAddress.parse(email, false);
msg.setRecipients(Message.RecipientType.TO, addrs);
msg.setSubject("Welcome!");
msg.setText("Test");
msg.setSentDate(new Date());
SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
t.connect("smtp.mailgun.org", "postmaster@my.custom.domain", "KEY");
t.sendMessage(msg, msg.getAllRecipients());
System.out.println("Email sent" + t.getLastServerResponse());
t.close();
依赖关系:Dependencies2
在 Google 云平台上 运行 时上面的代码什么都不做。
我猜您是在谈论 this tutorial 配置通过 Compute Engine 发送邮件(这解释了为什么它在您的 VM 实例上运行良好)。
该教程适用于 Compute Engine,如果是 App Engine 标准应用程序,您可以选择使用 Mail API, however, since Google is no longer accepting quota increases API,建议使用第三方服务,例如作为 MailGun 或 SendGrid。
要将您的 App Engine 标准应用程序(需要 Java 运行 时间)与这些第三方服务连接,您需要在 "pom.xml" 上指定 "dependicies"文件并使用 API 键修改您的 "app.yaml":
env_variables:
EMAIL_API_KEY: key-from-third-party
Email API 密钥将由第三方服务提供,例如,在 MailGun 的情况下,他们的 documentation 指定如下:
When you sign up for an account, you are given an API key. You authenticate to the Mailgun API by providing your API key in the request. You can manage your API key in the “Security” tab under the Account section of the Control Panel.
有关如何配置 App Engine 标准应用程序以连接这些第三方服务的分步说明,请参阅此 documentation。
编辑:
在你的情况下,你可能正在使用另一个依赖项(因此,依赖项错误)。创建代码时,您是否参考了 App Engine Java 8 文档示例或 Mailgun 示例?因为我注意到它们使用不同的依赖项,而且 App Engine 示例使用环境变量(根据您共享的代码片段,您没有使用)。
我的建议是遵循为 Google App Engine Standard Java 8 提供的示例。
这些是我在 App Engine 上成功启动和 运行ning 所采取的步骤:
1. 下载了 sample code。
2. 在 Mailgun 创建了一个帐户(简单帐户,未附加信用数据)。您将需要通过指定的电子邮件验证您的帐户。
3. 登录 MailGun 后,您将在左侧看到一个菜单,导航至“发送”>“概览”页面。
4. 在右边你会看到一个"Authorized Recipients"框,添加电子邮件或将收到电子邮件的人,他们也需要确认他们这边,所以为了测试,请尝试添加您可以访问的电子邮件。注意:如果您还没有 verified your domain.
,则需要执行此操作5. 复制您的默认域名(或您已验证的域名)的值。
6.在同一个框里有一个菜单link到"Api Keys",点击它,复制[=89=下面的键](这也是你的私钥,所以放在哪里要小心)。
7. 前往下载的 GCP 示例,然后编辑文件 "/mailgun/src/main/webapp/WEB-INF/appengine-web.xml" 使用这些值(域和密钥)。
8. 如果您使用 Maven 运行 命令:
mvn appengine:run (if you want to test locally)
或
mvn appengine:deploy (if you want to deploy to App Engine)
注意: 其中一些步骤对您来说可能看起来很明显,但我已经以这种方式进行了解释,以便其他人也可以遵循。