2016-08-04 8 views
1

ActiveMQとPlay Framework v2.4.2(Javaバージョン)を使用してエンドユーザに電子メールを送信するメッセージングシステムを開発しています。私はJMS/ActiveMQの技術者で初心者です。 ActiveMQサイトでthis Hello World exampleを開始点として使用しました。Playフレームワークで使用するJMS/ActiveMQ例外

私がプレイフレームワークとのActiveMQを実行しているテストするために、以下のようにテストクラスを作成し、すべてがOKだった:

public class ActiveMQMailApp { 

    public static void main(String[] args) throws Exception { 
     setup(); 
     MailConsumer.initService(); 
     for (int i =0;i<11;i++) MailProducer.sendMail(fakeMail()); 
    } 
    public static void setup(){ 
     FakeApplication fakeApplication = Helpers.fakeApplication(); 
     Helpers.start(fakeApplication); 
    } 

    private static Mail fakeMail() throws InterruptedException { 
     Thread.sleep(1000); 
     SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd hh:mm:ss"); 
     return new Mail("[email protected]", "[email protected]", "A Test Email", "<html><body><p>Date: <b> "+sdf.format(new Date())+" </b></p></body></html>"); 
    } 

} 

しかし、私は、メインアプリでこの正確なコードを使用する場合、この例外がスローさ:

javax.jms.JMSException: Could not create Transport. Reason: java.lang.RuntimeException: Fatally failed to create SystemUsageorg/apache/activemq/protobuf/BufferInputStream 
     at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36) 
     at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:332) 
     at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:345) 
     at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:303) 
     at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:243) 
     at ir.iais.salary.services.MailProducer.run(MailProducer.java:35) 
Caused by: java.lang.RuntimeException: Fatally failed to create SystemUsageorg/apache/activemq/protobuf/BufferInputStream 
     at org.apache.activemq.broker.BrokerService.getSystemUsage(BrokerService.java:1159) 
     ... 5 more 
Caused by: java.io.IOException: org/apache/activemq/protobuf/BufferInputStream 
     at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:39) 
     ... 11 more 
Caused by: java.lang.NoClassDefFoundError: org/apache/activemq/protobuf/BufferInputStream 
     at org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter.<init>(KahaDBPersistenceAdapter.java:65) 
     ... 13 more 
Caused by: java.lang.ClassNotFoundException: org.apache.activemq.protobuf.BufferInputStream 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 

マイMailProducerとMailConsumerクラスは、これらのようなものです:

public class MailProducer implements Runnable{ 
    public static final String AMQ_MAIL_QUEUE = "MAIL"; 
    public static final String BROKER_URL = "vm://localhost?broker.useJmx=false&persistent=false"; 
    private Mail mail; 

    public MailProducer(Mail mail) { 
     this.mail = mail; 
    } 

    public static void sendMail(Mail mail){ 
     Thread brokerThread = new Thread(new MailProducer(mail)); 
     brokerThread.setDaemon(false); 
     brokerThread.start(); 
    } 

    @Override 
    public void run() { 
     try { 
      // Create a ConnectionFactory 
      ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL); 

      // Create a Connection 
      Connection connection = connectionFactory.createConnection(); 
      connection.start(); 

      // Create a Session 
      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 

      // Create the destination (Topic or Queue) 
      Destination destination = session.createQueue(AMQ_MAIL_QUEUE); 

      // Create a MessageProducer from the Session to the Topic or Queue 
      MessageProducer producer = session.createProducer(destination); 
      producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 

      // Create a messages 
      TextMessage textMessage = session.createTextMessage(new Gson().toJson(mail)); 
      // Tell the producer to send the message 
      System.out.println("Sent message: "+ new Gson().toJson(mail) + " : " + Thread.currentThread().getName()); 
      producer.send(textMessage); 

      // Clean up 
      session.close(); 
      connection.close(); 
     } 
     catch (Exception e) { 
      System.out.println("Caught: " + e); 
      e.printStackTrace(); 
     } 
    } 
} 




public class MailConsumer implements Runnable, ExceptionListener { 
    private static final Logger logger = getLogger(MailConsumer.class); 
    private static Thread mailConsumerService; 

    public static synchronized void initService() { 
     MailConsumer mailConsumer = Play.application().injector().instanceOf(MailConsumer.class); 
     if (mailConsumerService != null) { 
      logger.info("STOPPING MailConsumer thread."); 
      mailConsumerService.interrupt(); 
     } 
     logger.info("Starting MailConsumer thread."); 
     mailConsumerService = new Thread(mailConsumer); 
     mailConsumerService.setDaemon(true); 
     mailConsumerService.setName("MailConsumer Service"); 
     mailConsumerService.start(); 
     logger.info("MailConsumer thread started."); 
    } 

    @Inject 
    private MailerClient mailerClient; 

    @Override 
    public void run() { 
     try { 
      // Create a ConnectionFactory 
      ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(MailProducer.BROKER_URL); 

      // Create a Connection 
      Connection connection = connectionFactory.createConnection(); 
      connection.start(); 

      connection.setExceptionListener(this); 

      // Create a Session 
      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 

      // Create the destination (Topic or Queue) 
      Destination destination = session.createQueue(MailProducer.AMQ_MAIL_QUEUE); 

      // Create a MessageConsumer from the Session to the Topic or Queue 
      MessageConsumer consumer = session.createConsumer(destination); 

      while (!Thread.currentThread().isInterrupted()) { 
       // Wait for a message 
       Message message = consumer.receive(); 

       if (message instanceof TextMessage) { 
        TextMessage textMessage = (TextMessage) message; 
        String text = textMessage.getText(); 
        System.out.println("Received: " + text); 
        Mail mail = new Gson().fromJson(text, Mail.class); 
        Email email = new Email(); 
        email.setFrom(mail.getFrom()); 
        email.setTo(mail.getTo()); 
        email.setSubject(mail.getSubject()); 
        email.setBodyHtml(mail.getBodyHtml()); 
        System.out.println("sending email..."); 
        mailerClient.send(email); 
        System.out.println("email sent!"); 
       } else { 
        System.out.println("Received: " + message); 
        logger.info("message type: "+message.getClass().getSimpleName()); 
       } 

      } 
      logger.info("MailConsumer interrupted."); 
      consumer.close(); 
      session.close(); 
      connection.close(); 
     } catch (Exception e) { 
      if (e instanceof InterruptedException) { 
       logger.info("MailConsumer thread interrupted."); 
      } else { 
       logger.error(e.getLocalizedMessage(), e); 
      } 
     } 
    } 

    public synchronized void onException(JMSException ex) { 
     System.out.println("JMS Exception occured. Shutting down client."); 
     logger.error("ErrorCode=" + ex.getErrorCode() + " , " + ex.getMessage(), ex); 
    } 
} 

私はこのようなメインアプリでMailProducerを呼び出す:

public Result sendTestMail(){ 
    if(!DevStatus.gI().isInDebugMode()) return badRequest("You'r not in Development Env."); 
    SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd hh:mm:ss"); 
    Mail mail = new Mail("[email protected]", "[email protected]", "A Test Email", "<html><body><p>Date: <b> " + sdf.format(new Date()) + " </b></p></body></html>"); 
    MailProducer.sendMail(mail); 
    return ok("email sent! "+ sdf.format(new Date())); 

問題がorg.apache.activemq.protobuf.BufferInputStreamあるようだがクラスパスにありません。 build.sbtに"org.apache.activemq.protobuf" % "activemq-protobuf" % "1.1"を追加しましたが、何も変わりませんでした。ブローカーURIにpersistent=falseを追加してActiveMQの永続性を無効にしましたが、機能しませんでした。

どうすればよいですか? ActiveMQをPlay Frameworkと一緒にJMSとして使用することは理にかなっていますか?または、Play Frameworkと連携するためのより良いJMSが用意されていますか? Akkaはどうですか?

編集:私のActiveMQの関連depsのは、以下のとおりです。

"org.apache.activemq" % "activemq-broker" % "5.13.4", 
    "org.apache.activemq" % "activemq-client" % "5.13.4", 
    "org.apache.activemq" % "activemq-kahadb-store" % "5.13.4", 
    "org.apache.activemq.protobuf" % "activemq-protobuf" % "1.1", 

編集2:私は"org.apache.activemq" % "activemq-all" % "5.14.0"で上記の依存関係を置き換え、メインアプリが動作するように始めました!最初に問題が解決され、ActiveMQパッケージに関連していると思っていましたが、ActiveMQMailAppテストクラスが上記と同じ例外を投げていることに気付きました!私はこの単純なMavenプロジェクト(フレームワークではない)でこのテストクラスを実行しました。私はこのエラーが後で戻ってくるのではないかと心配しています。実際に何が起こっているのですか?

+0

は、私はそれがあなたの質問に答えていない知っている依存関係リスト – arseniyandru

+0

を入力してください:

それを修正する方法は、明示的にジャータイプのアーティファクトを導入することです。 akkaを使用しない、または未来を使用してメールを送信するための根拠は何ですか?また、スレッドが実行されるたびにactivemq接続ファクトリを作成しているように見えます。インスタンスを取得して必要なときに再利用する方が良いでしょう。また、activemq-all依存関係を使用するとどうなりますか?示された例外は、protobufおよびkahadb依存関係が見つからないことを示します(SystemUsageのgetPersistenceAdapter())。あなたがアプリを動かすまで持続性を消してから、持続性に訴えましょう。 –

+1

@youhansちょうど確かめてください: 'sbt update'または' activator update'を実行しましたか? Akka/ActiveMQに関する質問については、[this](http://stackoverflow.com/questions/5693346/when-to-use-actors-instead-of-messaging-solutions-such-as-websphere-mq-or -tibco)が役立ちます。 ActiveMQを使用する必要がある場合を除き、Akkaを試してください。 – Salem

答えて

1

この依存関係をpomに追加します。

<dependency> 
     <groupId>org.apache.activemq</groupId> 
     <artifactId>activemq-kahadb-store</artifactId> 
     <scope>runtime</scope> 
    </dependency> 

thisを参照してください。

+0

'activemq-kahadb-store'の依存関係を' 'org.apache.activemq"% "activemq-kahadb-store"% "5.13.4"% "runtime" 'に変更しましたが、動作しませんでした。 – youhans

+0

上記のバージョンでバージョンを指定する必要もありました $ {activemq.version}

1

この問題は、解像度システムとしてアイビー(ivy)を使用し、何らかの理由でactivemq-protobufに決定された使用パッケージタイプmaven-pluginsのために導入されました。

のmavenは、コンパイルの瓶などのアーティファクトを解決蔦(またはSBTは、私は本当にわからないので、それはだ)間にはにはjarファイルが存在しないようので、SBTは、この依存関係を無視し、タイプmaven-plugins代わりの種類jarとしてこれを解決しますこの依存関係。

libraryDependencies += "org.apache.activemq.protobuf" % "activemq-protobuf" % "1.1" jar() 
+0

非常に参考になりました。 – Olaf

関連する問題