Ich entwickle ein Messaging-System mit ActiveMQ und Play Framework v2.4.2 (Java-Version), um E-Mails an Endbenutzer zu senden. Ich bin Neuling bei JMS/ActiveMQ-Technikern. Ich habe this Hello World example bei ActiveMQ Website als Ausgangspunkt verwendet. ActiveMQ mit Play-FrameworkJMS/ActiveMQ-Ausnahme mit Play-Framework
Ich habe wie unten eine Test-Klasse zu testen, laufen und alles war in Ordnung:
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>");
}
}
Aber wenn ich genau diesen Code in Haupt App verwenden, diese Ausnahme ausgelöst:
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)
Meine MailProducer und MailConsumer Klassen sind wie diese:
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);
}
}
Ich nenne MailProducer in Haupt-App wie folgt aus:
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()));
Es scheint, das Problem ist org.apache.activemq.protobuf.BufferInputStream
nicht in Classpath ist. Ich habe "org.apache.activemq.protobuf" % "activemq-protobuf" % "1.1"
zu build.sbt hinzugefügt, aber nichts hat sich geändert. Ich habe ActiveMQ-Persistenz auch deaktiviert, indem ich persistent=false
Broker-URI hinzugefügt habe, aber es hat nicht funktioniert.
Was kann ich tun? Ist es sogar sinnvoll, ActiveMQ mit Play Framework als JMS zu verwenden? Oder gibt es etwas besseres JMS, um mit Play Framework zu arbeiten? Was ist mit Akka? !!
Edit: Mein ActiveMQ Zusammenhang deps sind:
"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",
Edit 2: Ich über Abhängigkeiten mit "org.apache.activemq" % "activemq-all" % "5.14.0"
und die Haupt-App gestartet ersetzt zu arbeiten! Ich dachte zuerst das Problem wurde gelöst und ist mit den ActiveMQ-Paketen verwandt, aber ich erkannte, dass die ActiveMQMailApp-Testklasse jetzt dieselbe Ausnahme wie oben wirft! Ich habe diese Testklasse in einem neuen einfachen Maven-Projekt (kein Spiel-Framework) durchgeführt und alles war in Ordnung! Ich fürchte, dieser Fehler kommt später zurück. Was passiert eigentlich ?!
Bitte geben Liste Abhängigkeiten – arseniyandru
ich weiß es nicht Ihre Frage nicht beantworten. Was ist der Grund dafür, Akka oder nur eine Zukunft nicht zu verwenden und damit die E-Mail zu versenden? Außerdem scheint es, dass Sie jedes Mal, wenn Ihr Thread ausgeführt wird, die activemq-Verbindungsfactory erstellen - besser, wenn Sie eine Instanz davon erhalten und diese bei Bedarf wiederverwenden.Was passiert auch, wenn Sie die activemq-all-Abhängigkeit verwenden - die Ausnahme, die Sie gezeigt haben, verweist auf die fehlende Abhängigkeit von Protobuf und Kahadb (getPersistenceAdapter() von SystemUsage). Deaktivieren Sie die Persistenz für den Moment, bis die App funktioniert und greifen Sie dann auf Persistenz zurück. –
@youhans Nur um sicher zu gehen: hast du 'sbt update' oder' activator update' ausgeführt? In Bezug auf die Akka/ActiveMQ-Frage, siehe [this] (http://stackoverflow.com/questions/5693346/when-to-use-actors-inst-of-messaging-solutions-such-as-websphere-mq-or -tibco) hilft. Wenn Sie ActiveMQ nicht verwenden müssen, sollten Sie Akka einen Versuch geben – Salem