【问题标题】:Twilio/Dropwizard runtime errorTwilio/Dropwizard 运行时错误
【发布时间】:2017-02-14 14:24:46
【问题描述】:

我正在尝试让 Twilio 在 Dropwizard 应用程序中工作。程序可以编译,但是在引导服务器时我经常遇到以下故障。

$ sudo ./startpiservice.sh
Exception in thread "main" java.lang.NoClassDefFoundError:  com/fasterxml/jackson/databind/type/ReferenceType at  com.fasterxml.jackson.datatype.guava.GuavaModule.setupModule(GuavaModule.java:55 ) at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:550) at io.dropwizard.jackson.Jackson.configure(Jackson.java:54) at io.dropwizard.jackson.Jackson.newObjectMapper(Jackson.java:24) at io.dropwizard.setup.Bootstrap.<init>(Bootstrap.java:64) at io.dropwizard.Application.run(Application.java:72) at applicationconfiguration.HomeApplication.main(HomeApplication.java:71) Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.type.ReferenceType at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 7 more

整个文件都可以在我的 Dropbox 上找到...对不起,我在做我的日常工作,无法访问 GitHUb 将其上传到那里。

https://www.dropbox.com/sh/or5v14uyyjplvmr/AAB4uoHdRDYLZVylUfGNotkfa?dl=0

有问题的类是 SMSResource.java,位于 \pirestservice\src\main\java\resources\SMSResource.java

代码在没有任何 Twilio 的代码语句和导入的情况下编译和运行,但是一旦我使用导入语句和代码语句,程序在引导期间就会失败。

我对使用 Maven 和 Dropwizard 比较陌生……这是依赖项冲突的问题吗?我错过了什么吗? Twilio 代码在一个简单的独立程序中工作......但在 Dropwizard 中却不行。

~~~~~~~~~~~~~~~~~~~~~~2017 年 3 月 2 日更新~~~~~~~~~~~~~~~~~~

根据 hortega 的建议,我修改了 Maven POM 文件并编译了程序,并在部署时运行了我的服务器。除了我需要的“/sendsms”之外,所有方法调用都有效。这是POM文件、java类文件和stacktrace的一部分。

<!-- Twilio -->
<dependency>
    <groupId>com.twilio.sdk</groupId>
    <artifactId>twilio</artifactId>
    <version>(7.0,7.9)</version>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </exclusion>
    </exclusions>
</dependency>

package resources;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;

import authentication.User;
import database.AccountDAO;
import database.UserDAO;
import io.dropwizard.hibernate.UnitOfWork;


/**
 * This class defines the URLs and provides the interface to HTTP requests and works
 * with the class PiGpioService to set and retrieve information from the model.
 */
@Path("/smsnotification")
@RolesAllowed("ADMIN")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
public class SMSResource implements GpioObserver
{
    private static final Logger LOGGER = LoggerFactory.getLogger(SMSResource.class);
    private final AccountDAO accountDAO;
    private final UserDAO userDAO;
    private int count;
    private Timer timer;
    private boolean timerSet = false;

    public SMSResource(AccountDAO accountDAO, UserDAO userDAO)
    {
        this.accountDAO = accountDAO;
        this.userDAO = userDAO;
    }

    /**
     * method called by GpioRepresentation class when there is a
     * change in state on garage door.
     * @param String state
     */
    public void update(String state)
    {   
        //if state is HIGH trigger a timer to start.  Kill the timer if
        //the state is low.
        if(state.equals("HIGH"))
        {
            //conditional to prevent multiple Timer objects
            if(!timerSet)
            {
                timer = new Timer();
                int delay = (20 * 60 * 1000);
                int period = (20 * 60 * 1000);

                //schedule first message to be sent when door is open 20 minutes.
                //then send a message every 20 minutes to a maximum of
                //3 times.
                MessageExecutor msgExec = new MessageExecutor();
                timer.schedule(msgExec, delay, period);
                timerSet = true;
            }
        }
        else
        {
            //cancel timer if the garage door is closed and reset the count
            timer.cancel();
            count = 0;
            timerSet = false;
        }
    }

    /**
     * Send an SMS text message.
     * FOR TESTING ONLY
     */
    @GET
    @Path("/sendsms")
    @UnitOfWork
    public Response sendSMSMessage()
    {
        List<User> users;
        List<TwilioAccount> accountDetails;
        int index = 0;

        users = userDAO.getAllUsers();
        accountDetails = accountDAO.getAccountDetails(); 

        Twilio.init(accountDetails.get(index).getSID(), accountDetails.get(index).getToken()); 

        for(User u : users)
        {
            LOGGER.info("SendSMS URL Works and I can get my USER and TWILIO Details,"
                    + "User {}, phone number {}, SID = {}, token = {}, from# = {}.", 
                    u.getName(), u.getPhoneNumber(), accountDetails.get(index).getSID(), accountDetails.get(index).getToken(),
                    accountDetails.get(index).getPhoneNumber());

            Message message = Message
                    .creator(new PhoneNumber(u.getPhoneNumber()), new PhoneNumber(accountDetails.get(index).getPhoneNumber()),
                        "This is the ship that made the Kessel Run in fourteen parsecs?")
                    .setMediaUrl("https://c1.staticflickr.com/3/2899/14341091933_1e92e62d12_b.jpg")
                    .create();

        }

        return Response.ok("message(s) sent").build();
    }

    /**
     * This private (inner) class is responsible for initiating a message
     * being sent every 20 minutes to alert that the garage door has been
     * left open.
     */
    private class MessageExecutor extends TimerTask
    {
        @Override
        @UnitOfWork
        public void run()
        {

            if(count < 3)
            {
                List<User> users;
                List<TwilioAccount> accountDetails;
                int index = 0;

                users = userDAO.getAllUsers();
                accountDetails = accountDAO.getAccountDetails(); 

                //Twilio.init(accountDetails.get(index).getSID(), accountDetails.get(index).getToken());

                for(User u : users)
                {
                    LOGGER.info("SendSMS URL Works and I can get my USER and TWILIO Details,"
                            + "User {}, phone number {}, SID = {}, token = {}, from# = {}.", 
                            u.getName(), u.getPhoneNumber(), accountDetails.get(index).getSID(), accountDetails.get(index).getToken(),
                            accountDetails.get(index).getPhoneNumber());

                    //Message message = Message
                      //      .creator(new PhoneNumber(u.getPhoneNumber()), new PhoneNumber(accountDetails.get(index).getPhoneNumber()),
                        //        "This is the ship that made the Kessel Run in fourteen parsecs?")
                          //  .setMediaUrl("https://c1.staticflickr.com/3/2899/14341091933_1e92e62d12_b.jpg")
                            //.create();

                }
                count++;
            }
        }   
    }
}

这里是堆栈跟踪/记录器的输出:

INFO  [2017-03-03 02:14:29,347] authentication.BasicAuthenticator: User: Mike logged in with email: mike@xxxxxxx.ca and password: xxxxxx.
INFO  [2017-03-03 02:14:29,374] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener: Session Metrics {
    531871 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    5236262 nanoseconds spent preparing 1 JDBC statements;
    6003028 nanoseconds spent executing 1 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
INFO  [2017-03-03 02:14:29,571] resources.SMSResource: SendSMS URL Works and I can get my USER and TWILIO Details,User Mike, phone number +1xxxxxxxxxx, SID = ACxxxxxxxxxxxxx, token = 1xxxxxxxxxx5, from# = +1xxx5xx8xx9.
INFO  [2017-03-03 02:14:37,092] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener: Session Metrics {
    526871 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    5925736 nanoseconds spent preparing 2 JDBC statements;
    6532189 nanoseconds spent executing 2 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    29239673 nanoseconds spent executing 2 partial-flushes (flushing a total of 2 entities and 2 collections)
}
ERROR [2017-03-03 02:14:37,113] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: 0cd82e2d769a36c4
! com.twilio.exception.ApiException: java.lang.IllegalStateException
! at com.twilio.http.NetworkHttpClient.makeRequest(NetworkHttpClient.java:89)
! at com.twilio.http.HttpClient.reliableRequest(HttpClient.java:38)
! at com.twilio.http.HttpClient.reliableRequest(HttpClient.java:22)
! at com.twilio.http.TwilioRestClient.request(TwilioRestClient.java:42)
! at com.twilio.rest.api.v2010.account.MessageCreator.create(MessageCreator.java:307)
! at com.twilio.rest.api.v2010.account.MessageCreator.create(MessageCreator.java:25)
! at com.twilio.base.Creator.create(Creator.java:45)
! at resources.SMSResource.sendSMSMessage(SMSResource.java:139)
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
! at java.lang.reflect.Method.invoke(Method.java:498)
! at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
! at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
! at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
! at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
! at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
! at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
! at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
! at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
! at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
! at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
! at io.dropwizard.jetty.NonblockingServletHolder.handle(NonblockingServletHolder.java:49)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689)
! at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:34)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:50)
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:44)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)
! at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
! at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174)
! at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106)
! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
! at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:240)
! at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:51)
! at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:459)
! at io.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.java:68)
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:56)
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:169)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
! at org.eclipse.jetty.server.Server.handle(Server.java:524)
! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
! at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
! at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
! at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
! at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
! at java.lang.Thread.run(Thread.java:745)
192.168.1.224 - - [03/Mar/2017:02:14:37 +0000] "GET /smsnotification/sendsms HTTP/1.1" 500 110 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" 8177

我已经受够了把头撞到墙上的夜晚......如果有人可以提供建议,请告诉我。

【问题讨论】:

    标签: java twilio dropwizard


    【解决方案1】:

    你缺少杰克逊的依赖。将此添加到您的 pom.xml

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-guava -->
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-guava</artifactId>
        <version>2.0.3</version>
    </dependency>
    

    【讨论】:

    • 谢谢。我将在今晚或明天回家后实施此计划,并让您知道结果如何。
    • 我添加了这些依赖项,但应用程序在引导期间仍然崩溃。完全相同的错误。 :-(
    【解决方案2】:

    您的两个依赖项正在提取不同版本的 Jackson 库。这里mvn dependency:tree -Dverbose 是你的朋友,它会告诉你哪些依赖是冲突的:

    ...
    [INFO] +- io.dropwizard:dropwizard-core:jar:1.0.5:compile
    [INFO] |  +- io.dropwizard:dropwizard-util:jar:1.0.5:compile
    [INFO] |  |  +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.7.8:compile - omitted for conflict with 2.4.3)
    ...
    [INFO] \- com.twilio.sdk:twilio:jar:7.5.0:compile
    ...
    [INFO]    +- com.fasterxml.jackson.core:jackson-databind:jar:2.4.3:compile
    [INFO]    |  +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.4.0:compile - omitted for conflict with 2.4.3)
    ...
    

    您可以在这里看到dropwizard-coretwilio 使用不同版本的不同Jackson 包。通常,当你看到这个时,很有可能 Maven 使用了错误的版本,因为它没有足够的信息。所以我们应该告诉它使用哪个版本的Jackson(一般我们选择最新的版本)。有几种方法可以做到:

    1. 依赖管理:在这个块中添加冲突的依赖允许你为整个项目选择它们的版本。在&lt;dependencies&gt;之外添加下一个块:

      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-core</artifactId>
                  <version>2.7.8</version>
              </dependency>
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-annotations</artifactId>
                  <version>2.7.8</version>
              </dependency>
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-databind</artifactId>
                  <version>2.7.8</version>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
    2. 排除依赖项上的包:这种方式为您提供更细粒度的控制。只需在您希望忽略这些软件包版本的依赖项中添加 &lt;exclusions&gt; 块。在这种情况下,将是 Twilio,因为它具有最旧版本的冲突库。

       <dependency>
          <groupId>com.twilio.sdk</groupId>
          <artifactId>twilio</artifactId>
          <version>7.5.0</version>
          <exclusions>
              <exclusion>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-core</artifactId>
              </exclusion>
              <exclusion>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-annotations</artifactId>
              </exclusion>
              <exclusion>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-databind</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      

    当您开始使用 Maven 时,这个问题会困扰您几次,但 dependencies 插件在这里真的很有帮助。

    我在twilio-java 上创建了一个 PR 来升级这些依赖项,但如果您不想等待,只需使用上述方法之一。

    About Maven's dependency mechanism.

    【讨论】:

    • 谢谢。您的建议有效,我可以编译和运行服务器,但是,我遇到了另一个错误。我将使用堆栈跟踪和 java 类文件编辑我的帖子。
    【解决方案3】:

    我找到了这个问题的真正答案。问题在于 Ubuntu Mate for Raspberry Pi 发行版中提供的 JVM。他们提供 OpenJDK。经过大量在线调试后,我开始将操作系统和 JVM 视为问题的根源,当我将 OpenJDK 换成 Oracle JDK 时,一切都按我预期的方式运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多