【问题标题】:Class not found exception for AppEngine with SendGrid使用 SendGrid 的 AppEngine 未找到类异常
【发布时间】:2016-08-16 08:37:00
【问题描述】:

我正在使用带有 Java 的 Google AppEngine。
我正在使用 SendGrid API 发送电子邮件。 所以我下载了 SendGrid 库 (https://github.com/sendgrid/sendgrid-java)。
我用 Java 在 AppEngine 之外编写了一个测试应用程序,它可以正确发送电子邮件。
当我尝试使用 AppEngine 运行应用程序时,它显示此错误:

java.lang.NoClassDefFoundError: org/apache/http/ssl/SSLContexts
    at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:966)
    at org.apache.http.impl.client.HttpClients.createDefault(HttpClients.java:58)
    at com.sendgrid.Client.<init>(Client.java:55)
    at com.sendgrid.SendGrid.<init>(SendGrid.java:29)
    at com.fms.advocacy.AdvocacyMail.send(AdvocacyMail.java:40)
    at com.fms.advocacy.AdvocacyMail.send(AdvocacyMail.java:36)
    at com.fms.advocacy.AdvocacyMail.send(AdvocacyMail.java:32)
    at com.fms.advocacy.api.auth.AuthenticationApi.forgotPassword(AuthenticationApi.java:186)
    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:130)
    at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:363)
    at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
    at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
    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.fms.advocacy.filters.AccessRuleFilter.doFilter(AccessRuleFilter.java:49)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.fms.advocacy.filters.AuthFilter.doFilter(AuthFilter.java:32)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.fms.advocacy.filters.ErrorHandlerFilter.doFilter(ErrorHandlerFilter.java:36)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    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:128)
    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:50)
    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:512)
    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)

谁能解决这个问题?

这是我的 pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>

    <groupId>com.fms</groupId>
    <artifactId>advocacy</artifactId>

    <properties>
        <app.id>xyz-abc</app.id>
        <app.version>1</app.version>
        <appengine.version>1.9.42</appengine.version>
        <gcloud.plugin.version>2.0.9.74.v20150814</gcloud.plugin.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
    </properties>

    <prerequisites>
        <maven>3.1.0</maven>
    </prerequisites>

    <dependencies>
        <!-- Compile/runtime dependencies --> 
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>   
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-1.0-sdk</artifactId>
            <version>${appengine.version}</version>
        </dependency>  
        <dependency>
            <groupId>com.sendgrid</groupId>
            <artifactId>sendgrid-java</artifactId>
            <version>3.0.8</version>
            <type>jar</type>
        </dependency>  
    </dependencies>

    <build>
        <!-- for hot reload of the web application -->
        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <version>3.1</version>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archiveClasses>true</archiveClasses>
                    <webResources>
                        <!-- in order to interpolate version from pom into appengine-web.xml -->
                        <resource>
                            <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                            <filtering>true</filtering>
                            <targetPath>WEB-INF</targetPath>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.google.appengine</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>${appengine.version}</version>
                <configuration>
                    <enableJarClasses>false</enableJarClasses>
                    <version>${app.version}</version>
                    <address>0.0.0.0</address>
                    <port>8888</port>
                    <jvmFlags>
                        <jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8001,server=y,suspend=n</jvmFlag>
                    </jvmFlags>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.google.appengine</groupId>
                <artifactId>gcloud-maven-plugin</artifactId>
                <version>${gcloud.plugin.version}</version>
                <configuration>
                    <set_default>true</set_default>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>versions-maven-plugin</artifactId>
                    <version>2.1</version>
                    <executions>
                        <execution>
                            <phase>compile</phase>
                            <goals>
                                <goal>display-dependency-updates</goal>
                                <goal>display-plugin-updates</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <!--This plugin's configuration is used to store Eclipse m2e settings 
                    only. It has no influence on the Maven build itself. -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>
                                            org.codehaus.mojo
                                        </groupId>
                                        <artifactId>
                                            versions-maven-plugin
                                        </artifactId>
                                        <versionRange>
                                            [2.1,)
                                        </versionRange>
                                        <goals>
                                            <goal>
                                                display-plugin-updates
                                            </goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

【问题讨论】:

  • 请说明org.apache.http.ssl.SSLContext 类是如何包含在类路径中的。

标签: java google-app-engine sendgrid


【解决方案1】:

Sendgrid 依赖于 Apache httpclient,这在 GAE 上可能存在问题。

他们有一个特殊的 GAE 库:

https://github.com/sendgrid/sendgrid-google-java

另见:

https://cloud.google.com/appengine/docs/java/mail/sendgrid

所以使用sendgrid-google-java 而不是sendgrid-java。

【讨论】:

  • 我试过了。但这是非常基本的。也没有可用于附件和模板的文档
  • 它似乎只是 Sendgrid 的 v2 web api 的包装器:sendgrid.com/docs/API_Reference/Web_API/using_the_web_api.html 所以你可以使用那里的文档来查看如何发送附件等。实际上最好只使用 v3 api马上不要使用这个 sengrid-google-java 库本身。只需确保使用 java.net.HttpURLConnection 或 Google 自己的 httpclient。
  • 好的。我会试试的。感谢回复
【解决方案2】:

看起来您错过了类路径中的httpclient&lt;version&gt;.jar。

为 gradle 添加以下依赖项:

compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2'

【讨论】:

  • 这不应该是评论而不是答案吗?
  • @ppeterka 没有。这是答案
  • 你确定吗?这个问题是完全不完整的......另外,OP 在他的电脑上写了and it is sending emails properly 等,东西似乎工作,所以 that 类路径是可以的。 AppEngine 上的类路径有问题 - 比如this question 中的版本冲突。
  • 在我的工作程序中,我只为应用引擎和 Sendgrid Java 客户端添加了 maven 存储库。 mvnrepository.com/artifact/com.sendgrid/sendgrid-java/3.0.8 另外,当我添加这个存储库时,maven 会自动下载其他需要的库吗?这不就是 maven 的全部理念吗?
  • @Harikrishnan 是的,这是 maven 的想法。但也可能是开发者不想添加一些jar,因为版本不同等等。所以有可能,你必须手动添加这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 1970-01-01
  • 2023-04-07
  • 2022-09-30
相关资源
最近更新 更多