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プロジェクト(フレームワークではない)でこのテストクラスを実行しました。私はこのエラーが後で戻ってくるのではないかと心配しています。実際に何が起こっているのですか?
は、私はそれがあなたの質問に答えていない知っている依存関係リスト – arseniyandru
を入力してください:
それを修正する方法は、明示的にジャータイプのアーティファクトを導入することです。 akkaを使用しない、または未来を使用してメールを送信するための根拠は何ですか?また、スレッドが実行されるたびにactivemq接続ファクトリを作成しているように見えます。インスタンスを取得して必要なときに再利用する方が良いでしょう。また、activemq-all依存関係を使用するとどうなりますか?示された例外は、protobufおよびkahadb依存関係が見つからないことを示します(SystemUsageのgetPersistenceAdapter())。あなたがアプリを動かすまで持続性を消してから、持続性に訴えましょう。 –
@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