ERLEDIGT
NEIN
NEIN
ANTWORTEN
12
12
ZUGRIFFE
7350
7350
EMPFEHLEN
-
30.08.05 16:19 #1
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Hier mal ein paar Beispiele zum Einsatz von Messaging mit JMS und JBossMQ
mit möglichst wenig Worten. Dazu verwenden wir den JBoss 4.0.2, Java 5
und Eclipse 3.1 incl. JBoss IDE.
Zunächst etwas Theorie:
Messaging beschreibt das Versenden von "Nachrichten" zwischen unterschiedlichen Komponenten. Die technologie die Java für Messaging bietet heißt JMS. JMS steht für Java Message Service und ist bestandteil der J2EE (JEE) Spezifikation. Die aktuelle Version der JMS Spezifikation lautet 1.1 und findet sich unter: http://java.sun.com/products/jms/docs.html . Bei JMS erfolgt der Nachrichtenversand immer an so genannte Destinations. Destinations sind die "Zielorte" der JMS Nachrichten. bei Destinations gibt es grundsätzlich 2 verschiende Typen die je nach Messaging-Modi Anwendung finden. Diese sind Queue mit dem Messaging Modi Point-to-Point und Topic mit dem Messaging Modi Publish-Subscribe. Point-to-Point Verbindungen erlauben das Versenden von Nachrichten von einem Client an genau einen Empfänger. (Es können sehr wohl mehrere Clients Nachrichten in die Queue senden und auch mehrere Clients aus der Queue lesen, jedoch wird eine eingehende Nachricht immer nur genau von einem Client empfangen dieses Verhalten ist jedoch in der Spezifiaktion nicht festgelegt... ). Beim Publish-Subscribe Modell erfolgt der Nachrichtenversand an ein Topic.Auch hier können mehrere Clients Nachrichten an ein Topic senden. Im Gegensatz zum Point-to-Point Modus empfängt hier jeder an diesem speziellen Topic registrierte (subscribe) Client jede an dieses Topic gesendete Nachricht.
Zum Einstieg hier mal ein Beispiel für beide Szenarien:
Zunächst Konfigurieren wir uns eine eigene Queue und ein eigenes Topic
innerhalb des JBoss Applikationsservers. Dazu wechseln wir in das Verzeichnis unserer Serverkonfiguration (Z.Bsp.: %JBOSS_HOME%/server/default) und editieren dort die Datei jbossmq-destinations-service.xml im verzeichnis ./deploy/jms
Dort ergänzen wir (beispielsweise am Ende) die beiden Einträge:
Code :1 2 3 4 5 6
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=TutorialsQueue"> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager </depends> </mbean>
und
Damit haben wir im JBoss die beiden Destinations TutorialsQueue und TutorialsTopic registriert. Diese sind innerhalb des JNDI über den NamenCode :1 2 3 4 5 6
<mbean code="org.jboss.mq.server.jmx.Topic" name="jboss.mq.destination:service=Topic,name=TutorialsTopic"> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager </depends> </mbean>
queue/TutorialsQueue und topic/TutorialsTopic zu finden.
Weitere Informationen zur Konfiguration von JMS findet man in der JBoss Dokumentation: http://www.jboss.com/products/jbossas/docs
(AdminGuide / DevelopersGuide / Getting Started Guide)
Ob wir das vor dem Starten von JBOSS oder zur (POST_STARTUP) Zeit machen ist dem JBoss egal. JBoss bekommt auch änderungen zur Laufzeit mit.
Wir beginnen nun mit einem Beispiel in einem Point-to-Point-Szenario.
Wir senden von einem Client eine Nachricht zur tutorialsQueue und lesen von einem Anderen Client die Nachricht aus der Queue. Dabei warten wir einmal selbst auf die Queue und anschließend verwenden wir einen sogenannten MessageConsumer.
Wir versenden eine Nachricht zur Queue:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
package de.tutorials.jmstutorial.ptp; import javax.jms.Message; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.naming.InitialContext; public class PointToPointQueueSenderExample { /** * @param args */ public static void main(String[] args) throws Exception{ InitialContext ctx = new InitialContext(); //Wir besorgen uns unsere Queue (Destination) aus dem JNDI Queue queue = (Queue) ctx.lookup("queue/TutorialsQueue"); //Wir besorgen uns eine ConnectionFactory für den Verbindungsaufbau //zum JBossMQ Dienst aus dem JNDI. QueueConnectionFactory qcf = (QueueConnectionFactory) ctx .lookup("ConnectionFactory"); QueueConnection qc = qcf.createQueueConnection(); qc.setClientID("JMS_Client_Sender"); QueueSession qsession = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); qc.start(); QueueSender qsender = qsession.createSender(queue); //Wir versenden 10 Nachrichten in die Queue for (int i = 0; i < 10; i++) { String text = "Hello " + System.currentTimeMillis(); Message msg = qsession.createTextMessage(text); qsender.send(msg); System.out.println("Sending: " + text); } String text = "EXIT " + System.currentTimeMillis(); Message msg = qsession.createTextMessage(text); qsender.send(msg); System.out.println("Sending: " + text); //Wir räumen auf... qc.stop(); qsender.close(); qsession.close(); qc.close(); ctx.close(); } }
Um zu sehen, ob tatsächlich Nachrichten in der Queue stehen gibt es prinzipiel mehrere Möglichkeiten. Hier werde ich näher auf zwei Möglichkeiten eingehen wobei beide über die JMX-Console abgewickelt werden. Die JMX-Console ist eine Web Anwendung mit der die im JBoss lebenden JMX-MBeans verwaltet werden können.
Die Zugriff zur JMX-Console gibt's in der Regel über den Webbrowser unter:
http://localhost:8080/jmx-console .Diese gibt es auch als "größeres" Applet jedoch beschränke ich mich hier nur auf die html Version. Unter der Domäne jboss innerhalb der JMX-Console findet sich der Eintrag: database=localDB,service=Hypersonic . Dieser Eintrag steht für die innerhalb des JBoss verwendete In-Memory Datenbank Hypersonic SQL. Klicken wir auf den Eintrag gelangen wir auf eine Seite in der wir
allerlei Enstellungen tätigen können... uns interessiert aber im Moment nur die Operation "void startDatabaseManager()". Dort klicken wir auf den InvokeButton und alsbald sehen wir, dass sich eine kleine Swing Anwendung aufpoppen. Hier haben wir nun eine Art Datenbank-Explorer für die Hypersonic SQL DB. Führen wir nun im Abfragefenster die Abfrage: select * from jms_messages; aus so sehen wir in dem Ergebnis Bereich eine ganze Reihe von JMS-Nachrichten.
Eine andere Möglichkeit wäre es über die JMS-Console unter der Domain: jboss.mq.destination zu schauen. Dort sind alle innerhalb des JBoss hinterlegten Destinations aufgezeigt. Klicken wir dort auf unsere name=TutorialsQueue,service=Queue können wir zum einen über das Attribut QueueDepth die Anzahl der aktuell innerhalb dieser Queue vorhandenen Nachrichten abfragen. Wollen wir uns die Nachrichten etwas genauer ansehen, dann müssen wir das über den invoke-Button der java.util.List listMessages() Operation tun.
Wir lesen die Nachrichten aus der Queue aus:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
package de.tutorials.jmstutorial.ptp; import java.util.Date; import javax.jms.Message; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueReceiver; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.InitialContext; public class PointToPointQueueRequestor { /** * @param args */ public static void main(String[] args) throws Exception{ InitialContext ctx = new InitialContext(); //Wir besorgen uns unsere Queue (Destination) aus dem JNDI Queue queue = (Queue) ctx.lookup("queue/TutorialsQueue"); //Wir besorgen uns eine ConnectionFactory für den Verbindungsaufbau //zum JBossMQ Dienst aus dem JNDI. QueueConnectionFactory qcf = (QueueConnectionFactory) ctx .lookup("ConnectionFactory"); QueueConnection qc = qcf.createQueueConnection(); qc.setClientID("JMS_Client_Requestor"); QueueSession qsession = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); qc.start(); QueueReceiver queueReceiver = qsession.createReceiver(queue); //Wir lesen Nachrichten aus der Queue TextMessage msg = null; //Maximal 1s auf neue Nachrichten warten... while((msg = (TextMessage) queueReceiver.receive(1000L))!= null){ System.out.println("Received: " + msg.getText()); } //Wir räumen auf... qc.stop(); queueReceiver.close(); qsession.close(); qc.close(); ctx.close(); } }
Wir Verwenden zur Abwechslung mal einen MessageConsumer, der uns einen nützlichen Listener Mechanismus bereitstellt.
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
package de.tutorials.jmstutorial.ptp; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueReceiver; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.InitialContext; public class PointToPointQueueMessageConsumerExample { /** * @param args */ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); // Wir besorgen uns unsere Queue (Destination) aus dem JNDI Queue queue = (Queue) ctx.lookup("queue/TutorialsQueue"); // Wir besorgen uns eine ConnectionFactory für den Verbindungsaufbau // zum JBossMQ Dienst aus dem JNDI. QueueConnectionFactory qcf = (QueueConnectionFactory) ctx .lookup("ConnectionFactory"); QueueConnection qc = qcf.createQueueConnection(); qc.setClientID("JMS_Client_MessageConsumer"); QueueSession qsession = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); qc.start(); QueueReceiver queueReceiver = qsession.createReceiver(queue); MessageConsumer consumer = qsession.createConsumer(queue); final boolean[] shouldExit = new boolean[1]; consumer.setMessageListener(new MessageListener() { public void onMessage(Message msg) { TextMessage txtMsg = (TextMessage) msg; try { String textContent = txtMsg.getText(); System.out .println("consumer received: " + textContent); if(textContent.indexOf("EXIT") >= 0){ shouldExit[0] = true; } } catch (JMSException e) { e.printStackTrace(); } } }); //Wir lassen den Cosumer ein "wenig" Zeit zum arbeiten... new Thread(){ { start(); } public void run(){ while(true){ try { if(shouldExit[0]){ break; } sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } } } }.join(); // Wir räumen auf... qc.stop(); queueReceiver.close(); qsession.close(); qc.close(); ctx.close(); } }
Das beispiel für den Publish-Subscribe Modus:
Hier der Subscriber ... (diesen starten wir in unserem Beispiel vor dem Publisher)
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
package de.tutorials.jmstutorial.ps; import javax.jms.JMSException; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; import javax.jms.TopicSession; import javax.jms.TopicSubscriber; import javax.naming.InitialContext; public class TopicSubscriberExample { /** * @param args */ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); // Wir besorgen uns unser Topic (Destination) aus dem JNDI final Topic topic = (Topic) ctx.lookup("topic/TutorialsTopic"); // Wir besorgen uns eine ConnectionFactory für den // Verbindungsaufbau // zum JBossMQ Dienst aus dem JNDI. TopicConnectionFactory tcf = (TopicConnectionFactory) ctx .lookup("ConnectionFactory"); final TopicConnection tc = tcf.createTopicConnection(); tc.start(); Runnable messageSubscriberAction = new Runnable() { public void run() { try { TopicSession session = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSubscriber subscriber = session .createSubscriber(topic); TextMessage message = (TextMessage) subscriber .receive(10000L); System.out.println(Thread.currentThread().getName() + " received: " + message.getText()); tc.stop(); subscriber.close(); session.close(); } catch (JMSException e) { e.printStackTrace(); } } }; new Thread(messageSubscriberAction).start(); Thread t = new Thread(messageSubscriberAction); t.start(); t.join(); tc.close(); ctx.close(); } }
Hier unser Publisher:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
package de.tutorials.jmstutorial.ps; import javax.jms.Session; import javax.jms.Topic; import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; import javax.jms.TopicPublisher; import javax.jms.TopicSession; import javax.naming.InitialContext; public class TopicPublisherExample { /** * @param args */ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); // Wir besorgen uns unsere Queue (Destination) aus dem JNDI Topic topic = (Topic) ctx.lookup("topic/TutorialsTopic"); // Wir besorgen uns eine ConnectionFactory für den // Verbindungsaufbau // zum JBossMQ Dienst aus dem JNDI. TopicConnectionFactory connectionFactory = (TopicConnectionFactory) ctx .lookup("ConnectionFactory"); TopicConnection connection = connectionFactory.createTopicConnection(); connection.setClientID("JMS_TOPIC_ExamplePublisher"); connection.start(); TopicSession session = connection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE); TopicPublisher publisher = session.createPublisher(topic); publisher.send(session.createTextMessage("Hallo Welt!")); connection.stop(); publisher.close(); session.close(); connection.close(); ctx.close(); } }
Als Beispiel für ein Request Response Szenario mit einer Queue dient uns im Folgenden ein Dienst der einen Integer Wert verdoppeln kann. Dazu senden wir von einem Client aus die Berechnungsanfrage als ObjectMessage an die Queue. Der "DoublerService" nimmt diese ObjectMessage aus der Queue führt die überaus "komplexe" Berechnung aus und sendet das Berechnungsergebnis direkt über die temporäre Queue zum Anfragenden zurück.
unser RequestResponseExample:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
package de.tutorials.jmstutorial.ptp; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueReceiver; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TemporaryQueue; import javax.naming.InitialContext; public class RequestResponseExample { /** * @param args */ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); // Wir besorgen uns unsere Queue (Destination) aus dem JNDI Queue queue = (Queue) ctx.lookup("queue/TutorialsQueue"); // Wir besorgen uns eine ConnectionFactory für den Verbindungsaufbau // zum JBossMQ Dienst aus dem JNDI. QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx .lookup("ConnectionFactory"); QueueConnection connection = connectionFactory.createQueueConnection(); connection.setClientID("JMS_Client_Sender"); QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); connection.start(); QueueSender sender = session.createSender(queue); ObjectMessage msg = session.createObjectMessage(Integer.valueOf(100)); //wir bauen uns eine temporäre Queue als Rückkanal für unsere Antwort... TemporaryQueue responseQueue = session.createTemporaryQueue(); msg.setJMSReplyTo(responseQueue); System.out.println("Sending: " + msg.getObject()); sender.send(msg); QueueReceiver responseReceiver = session.createReceiver(responseQueue); System.out.println("Waiting for answer..."); ObjectMessage response = (ObjectMessage)responseReceiver.receive(); System.out.println(response.getObject()); // Wir räumen auf... connection.stop(); responseReceiver.close(); sender.close(); session.close(); connection.close(); ctx.close(); } }
Der passende DoublerService...
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
package de.tutorials.jmstutorial.ptp; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueReceiver; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.naming.InitialContext; public class JMSDoublerService { /** * @param args */ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); // Wir besorgen uns unsere Queue (Destination) aus dem JNDI Queue queue = (Queue) ctx.lookup("queue/TutorialsQueue"); // Wir besorgen uns eine ConnectionFactory für den Verbindungsaufbau // zum JBossMQ Dienst aus dem JNDI. QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx .lookup("ConnectionFactory"); QueueConnection connection = connectionFactory.createQueueConnection(); connection.setClientID("JMSDoublerService"); QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); connection.start(); QueueReceiver requestReceiver = session.createReceiver(queue); ObjectMessage msg = (ObjectMessage) requestReceiver.receive(); Integer value = (Integer) msg.getObject(); //Wir besorgen uns die temporäre Queue für unsere Rückantwort... QueueSender sender = session.createSender((Queue) msg.getJMSReplyTo()); //Wir führen die hochkomplexe Berechnung durch... ObjectMessage response = session.createObjectMessage(Integer .valueOf(value.intValue() * 2)); sender.send(response); System.out.println("Sending: " + response.getObject()); // Wir räumen auf... connection.stop(); requestReceiver.close(); sender.close(); session.close(); connection.close(); ctx.close(); } }
//Edit:
todo:
-asynchroner vs. synchroner Aufruf.
-MessageSelector
-MessageTypen (TextMessage, ObjectMessage, MapMessage etc...)
- JMS Unterstützung von anderen Frameworks (Spring (springframework.org) / Lingo (http://lingo.codehaus.org/) beschreiben...
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
31.08.05 22:28 #2
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
MessageDrivenBeans sind EJB Komponenten mit denen asynchrone Nachrichtengetriggerte Ablauflogik abgebildet werden kann. Dieser EJB Typ kann nur indirekt von einem Client aus aufgerufen werden (durch das versenden einer Nachricht an eine entsprechende Queue oder ein entsprechendes Topic). MessageDrivenBeans werden in der Regel vom Container gepoolt. Das bedeutet, dass der Container mehrere Instanzen dieser MessageDrivenBean-Klasse vorhält um beim eintreffen von Nachrichten auf der zugeordneten Queue eine beliebige "unbeschäftigte" MessageDrivenBean Instanz aus dem Pool zu nehmen un diese mit der Abarbeitung der eingehenden Nachricht zu beauftragen.
Hier mal ein Beispiel für eine MessageDrivenBean:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
package de.tutorials.jms.mdb; import javax.ejb.CreateException; import javax.ejb.EJBException; import javax.ejb.MessageDrivenBean; import javax.ejb.MessageDrivenContext; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; /** * @author Tom * * Die Eigenschaften für den Deployment Descriptor der EJB Anwendung definieren wir * über XDoclet Kommentare... * @ejb.bean acknowledge-mode="Auto-acknowledge" * description="An Message Driven Bean example" * display-name="An Message Driven Bean example" * name="ExampleMessageDriven" destination-type = "javax.jms.Queue" * * Hiermit verknüpfen wir unser MessageDrivenBean mit der TutorialsQueue. * Wann immer eine Nachricht an diese Queue gesendet wird, nimmt sich ein * unbeschäftigtes MDB die Nachricht aus der Queue heraus und beginnt mit der * Verarbeitung. * @jboss.destination-jndi-name name = "queue/TutorialsQueue" */ public class ExampleMessageDrivenBean implements MessageDrivenBean, MessageListener{ public void ejbCreate(){ } public void setMessageDrivenContext(MessageDrivenContext arg0) throws EJBException { } public void ejbRemove() throws EJBException {} public void onMessage(Message msg) { TextMessage textMessage = (TextMessage)msg; try { System.out.println("MDB received: " + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
Im Anhang finden sich die Dateien als Eclipse Projekt.
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
05.09.07 23:52 #3
Hi Tom,
ich verstehe das Nachrichtenkonzept noch nicht ganz und hoffe das Du mir Nachhilfe geben kannst.
Ich möchte eine Applikation schreiben die dazu dienen soll Nachrichten im Team auszutauschen.
Dazu soll auch gehören, das neue Nachrichtenkanäle angelegt werden. Die sollen so lange gültigkeit haben, bis sie wieder jemand löscht.
Das Konzept von JBoss scheint so ausgelegt zu sein, dass nur von einem Administrator, der Zugriff auf das Dateisystem des Servers hat, neue Kanäle angelegt werden können.
Um meine Aufgabe zu lösen, müßte ich ein Bean schreiben , das hier ..\server\default\deploy\jms Dateien anlegen und löschen darf.
Würde das gehen, oder gibt es eine ganz andere Lösung dafür?
Ich hoffe die Frage ist nicht allzu dämlich.
-
07.09.07 10:07 #4
Kann es sein, dass du das fachliche Konzept der Nachricht mit dem technischen Konzept der Message verwechselst? Wenn ich "Nachrichten im Team austauschen" lese, klingt das eher wie das Konzept Mailingliste (auf ein Topic subscriben und dann die Nachrichten erhalten). Sowas setzt man nicht zwingendermaßen mit ner MessageDriven Architektur um. Eigentlich reicht es, eine zentrale Komponente zu schreiben, die die Registrierungen der Benutzer kenn (welcher User ist an welchem Topic interessiert) und einkommende Nachrichten an die interessierten Nutzer verteilt. Ganz einfach mithilfe einer Datenbank. Der einzige Punkt, an dem eine Message Sinn machen würde ist um die wahrscheinlich etwas länger dauernde Verteilung der Nachricht vom Absenden zu trennen.
Messages sind eher technischer Hammer für Asynchronität im Serverumfeld, wo man nicht mal eben nach belieben nen Thread aufmachen kann.
Gruß
Ollie
-
07.09.07 10:27 #5
Hi Ollie,
ein ApplicationServer scheint mir schon so eine zentrale Instanz zu sein, von der Du sprichst. Wenn ich den verwende muß ich mich auch nicht selber um Protokolle oder RMI kümmern.
Warum Datenbank? Ich will keine Daten abspeichern.
ApplicationServer bedeutet: "Wir wissen nicht wie Deine Applikation ausschaut, aber wir können Dir Dienste zur Verfügung stellen mit denen Du einfach eine schreiben kannst".
Ich schreibe gerade einen ServiceMBean der mir sagen soll welche Topics angelegt sind und der auch welche Anlegen und Löschen kann.
Das scheint ein weg zu sein der funktioniert.
-
07.09.07 11:02 #6
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
ich denke auch, das JMS in diesem Szenario der Overkill wäre...
wenn du zu Laufzeit Gruppen definieren und wieder auflösen willst solltest du dir mal jxta ansehen. Das ist ein Peer To Peer Messaging Framework. Auch dort kannst du einen Rechner als "quasi" Server abrichten, der dann das Gruppenmanagement übernimmt.
https://jxta.dev.java.net/
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
07.09.07 11:49 #7
Ok, danke.
Wen das so ist, dann hier die nächste Frage.
Ich möchte eine Client/Server-Applikation in Java bauen.
Die Clients werden mit EclipseRCP erstellt.
Es soll eine zentrale Datenbank dabei sein.
Der Großteil der Kommunikation wird ereignisorientiert sein, d.h. die Clients werden über Callbackfunktionen angestoßen.
Ein wesentlicher Bestandteil ist eine Ressourcenverwaltung. Wenn ein Benutzer etwas reserviert, dann sollen alle anderen Benutzer die diese Ansicht auch offen haben zeitnah davon informiert werden.
Zuerst wollte ich die Kommunikation mit RMI lösen, aber dabei hätte ich viele Dinge selber entwickelt die es schon woanders gibt, z.B. welcher Benutzer darf welche Objekte verwenden und welche Daten sehen und bearbeiten.
Ich muß dazu nicht JavaEE verwenden, ich möchte aber nur eine überschaubare Menge von unterschiedlichen Komponenten benutzen.
Mit welchem Framework würdet ihr das implementieren.
-
07.09.07 15:41 #8
Ich hatte einfach das Gefühl, dass du mit einem technischen Konzept auf ein fachliches Problem schießt, dass nur vom Namen her ähnlich ist. So nach dem Motto: "Ich möchte Nachrichten zwischen Usern austauschen - da gibts doch was, das heißt Messaging". So las sich das für mich in deinem ersten Post. "Nachrichten" kann ja erstmal alles sein. Hier im Forum kann ich auch anderen Usern Nachrichten schicken, und ich kann auch Threads beobachten und werde benachrichtigt, wenn es da was neues gibt. Trotzdem läuft das sicher nicht auf Basis von JMS
.
Auch deine restlichen Posts sind sehr technisch. Client/Server, EclipseRCP, ereignisorientierte Kommunikation. Und dann halt die Frage, die immer kommt: mit welchem Framework geht das?.
Deine Anmerkung zum AS spiegelte das auch recht gut wieder. Ich weiß was ein AS ist, was aber viel wichtiger ist, zu wissen, unter welchen Umständen ich überhaupt einen AS brauche - welche fachlichen Anforderungen es nötig machen, einen AS einzusetzen.
Ich geb halt ungern Tipps zum Thema Technologie, wenn ich nicht weiß, was die fachliche Anforderung dahinter ist. Und mir scheint, du hast die Technologie vor der Fachlichkeit beschlossen. Einfach weil soviel Technologiebuzzies im Raum rumfliegen, die allerdings auf eigentlich alles passen könnten nur scheinbar nicht auf dies Sachen, für die du Lösungen suchst ("welcher Benutzer darf welche Objekte verwenden" - sowas erschlägt ein technisches API wie RMI einfach nicht).
So, und jetzt noch was mehr on-topic
:
Wenn ich jetzt mal die Glaskugel ganz milchig durchschau... Client / Server, Remoting, asynchronität - das klingt schon arg nach nem Einsatzgebiet von Spring... vielleicht können wir ja noch detailerter werden.
Gruß
ollie
-
07.09.07 15:51 #9
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
*scnr*Wenn ich jetzt mal die Glaskugel ganz milchig durchschau... Client / Server, Remoting, asynchronität - das klingt schon arg nach nem Einsatzgebiet von Spring... vielleicht können wir ja noch detailerter werden.
Klingt im Moment nicht irgendwie alles was mehr als 3 Klassen involviert nach Spring?...
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
07.09.07 18:15 #10
Liebe Freunde, bitte verwirrt mich nicht.
Ich arbeite mich zwar gerade in EJB3.0 ein und kenne mich damit nicht allzu sehr aus, aber ich mache schon 20 Jahre Softwareentwicklung.
Das Lochkartenzeitalter ist gerade mal so an mir vorbei gegangen und alles andere habe ich aktiv mitgemacht. Was also Konzepte und Technologien in der IT-Welt angeht gibt es nur wenig was ich nicht kenne.
Ich bin ganz begeistert das ihr mir helft, nur was ihr mir sagt passt nicht zu dem was ich sonst gelesen habe.
Laut diversen Internetquellen, wie z.B. dieser hier: http://www.onjava.com/pub/a/onjava/2...ring-ejb3.html, ist Spring und EJB3.0 ungefähr das Gleiche.
EJB3.0 ist allerdings ein Industriestandard der von vielen Firmen getragen wird und zu dem es mehrere Implementierungen gibt. Spring hingegen wird nur von einer Firma getragen.
Ich habe schon viel schlechte Erfahrungen mit Singlevendorlösungen gemacht und darum Spring nicht in die nähere Wahl gezogen.
Ich habe mich erst sechs Wochen eingearbeitet und ich kann noch auf ein anderes Framework umsteigen. Das heißt aber auch sechs Wochen Arbeit wegwerfen.
@MSProductions, bitte sag mir wieviel Entwicklungserfahrung Du mit Spring oder EJB3.0 hast, damit ich Deine Aussage besser einschätzen kann.
@Tom, ich bin auf Deinen Beitrag aufmerksam geworden, weil ich nach Beispielen für Beans in JBoss gesucht habe. Dein Beispiel hat mir sehr geholfen. Was ist aus Deiner Sicht der Vorteil von Spring gegenüber EJB3.0?
Ich kenne nur die EJB3.0 implementierung JBoss. Da habe ich den Eindruck das man mit sehr wenigen Zeilen Code sehr viel Funktionalität programmieren kann. Die Performance kann ich nicht abschätzen. Meine geplante Applikation ist allerdings recht Oberflächenlastig und da ist der Flaschenhals sowieso immer der Mensch.
-
07.09.07 20:56 #11
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
also zunächst einmal EJB 3.0 und Spring sind nicht das gleiche noch nicht mal ungefähr.
EJB 3.0 ist die Neuauflage des Standard Komponenten Modells EJB 2.x für JEE Anwendungen nach der Spezifikation von Sun.
Spring ist ein Dependency Injection (DI) Framework / IoC (Inversion of Control) Container. DI in dem Sinne, das das Framework für dich die Abhängigkeiten zu dritten Komponenten auflöst (die Komponenten für dich fix und fertig konfiguriert). IoC meint hier nun, dass du nicht mehr dafür verantwortlich bist deine Komponenten programmatisch zu konfigurieren, das macht das Framework für dich. Zusätzlich kommt noch die Eigenschaft eines Containers hinzu. Das heißt du hast die Möglichkeit
den Lebenszyklus eines verwalteten Objects (Spring Managed / Komponente)
eben von Spring steuern zu lassen (aber um einiges flexibler als das bei EJB 3.0 Komponenten in einem EJB Container möglich ist) und Sichtbarkeitsbereiche (Scopes) definieren zu können (Prototype, Singleton,...). Weiterhin kommt noch der Framework Aspekt hinzu. Aufbauend auf dieser Infrastrutkur bietet das Springframework zahlreiche Module die generische hoch flexible Lösungen zu Remoting, Asynchronous Task Execution, Messaging, Security (ACEGI / Spring Security), Webframeworks (Spring Webflow, Spring Web MVC), Persistenz, AOP etc.
Siehe:
http://static.springframework.org/sp...roduction.html
Spring war und ist viel mehr und mächtiger / flexibler als EJB 2.x / 3.x
Was Spring und EJB gemeinsam haben ist das sie Dependency Injection Konzepte verwenden und Objekte verwalten können und verschiedene Interceptor Mechanismen mit sich bringen. Das ist bei EJB 3.0 jedoch alles etwas steifer und unflexibler als bei Spring.
Hier gibts noch einen Vergleich:
http://www.devx.com/Java/Article/32314/0/page/1
Wie schon gesagt Spring ist halt mehr, nicht nur eine Technologie wie EJB 3.0 sondern ein Framework.
Ich würde sagen, dass Spring mittlerweile auch schon ein Industriestandard ist. Nur mal zum Beispiel:EJB3.0 ist allerdings ein Industriestandard der von vielen Firmen getragen wird und zu dem es mehrere Implementierungen gibt. Spring hingegen wird nur von einer Firma getragen.
Ich habe schon viel schlechte Erfahrungen mit Singlevendorlösungen gemacht und darum Spring nicht in die nähere Wahl gezogen.
Im Projekt Pitchfork haben Interface 21 und BEA eine Spring basierte EJB 3.0 Implementierung hochgezogen
Mittlerweile haben sich alle großen Hersteller zu Spring Committed (IBM, BEA, Oracle,...)
Würde ich nicht so sehen. Zum einen mal sind die Konzepte so ähnlich, dass man sie ziemlich leicht übertragen kann. Weiterhin beschäftigt man sich bei der Arbeit mit EJB 3.0 mit den gleichen Tehcnologien die man auch für eine moderne Spring Anwendung benötigt (AOP, JPA, Transaction Handling via JTA, nur um mal ein paar zu nennen). Außerdem kann man Spring nachträglich in so ziemlich jede Anwendung einbringen. Spring arbeitet wunderbar mit EJB 3.0 zusammen. Dabei kann man bei der Verwendung von Spring die Konfiguration der Komponenten so umstellen, dass diese von Spring und nicht vom EJB Container bereitgestellt / verwaltet werden. Dabei muss man an den vorhandenen EJB 3.0 Komponenten nocht nicht mal was ändernIch habe mich erst sechs Wochen eingearbeitet und ich kann noch auf ein anderes Framework umsteigen. Das heißt aber auch sechs Wochen Arbeit wegwerfen.
Vorteile hat Spring IMHO ziemlich viele gegenüber EJB 3.0
Beispielsweise kann man bei Spring jedes Objekt per DI Konfigurieren lassen und nicht nur Objekte welche im JNDI abgelegt sind...
Ansonsten: Architectural benefits of Spring
http://www.theserverside.com/tt/arti...pringFramework
Sobald du dich mit Spring beschäftigst wirst du merken, dass du noch weniger Code (aber ein wenig mehr XML) schreiben musst um das selbe zu erreichenIch kenne nur die EJB3.0 implementierung JBoss. Da habe ich den Eindruck das man mit sehr wenigen Zeilen Code sehr viel Funktionalität programmieren kann.
Aber warten wir mal noch auf Olli, der hat sicherlich noch ein paar weitere Anmerkungen
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
07.09.07 21:16 #12
Hi Tom,
danke Dir. Ok, ich lasse JBoss erst mal sein und schaue mir Spring an.
Danke für die Links.
-
08.09.07 09:49 #13
Och, du hast das doch schon gut zusammengefasst. Ein Schwerpunkt der mir noch einfällt, ist Testbarkeit. EJBs sind grundsätzlich schwer zu testen, da technologieabhängig. Mit Spring ist es sehr leicht möglich technischen Code gut von geschäftlichem Code zu trennen. Das sorgt halt für einfache Unittestbarkeit. Auch Integrationstests sehen mit Spring wesentlich einfacher aus, als mit EJB.
Grundsätzlich stellt sich die Sache für mich so dar: es gibt nur wenige Fälle in denen ich eine EJB Implementierung einer Spring Implementierung vorziehen würde - verteilte Transaktionen z.B. oder bei bestimmten Infrastrukturkonfigurationen im Bereich JMS.
Ansonsten ist halt Spring der einfachere, integrativere und offenere Ansatz im Enterprisebereich. Ausserdem ist Spring OpenSource und Defacto Standard. Interface21 ist daher zwar entwickelnde Firma, aber die Community darum ist sowas von groß, dass es da keinen Stress geben wird. Das kann natürlich keiner Beweisen, aber das stell ich jetzt mal so in den Raum. Zu der Kernbenefit von Spring eher aus den Konzepten kommt: Dependency Injection, Strategy Pattern, AOP usw. D.h. du kannst eine Springanwendung auch mit wenig Umkonfigurationsaufwand auch in nem anderen DI Container laufen lassen z.B.
Zumal die EJB Integration von Spring auch sehr nett ist. In nem aktuellen Projekt, wo ich so ein wenig die Hand über der Architektur habe setzen wir zum Beispiel Spring hinter einer 2.1er MessageDrivenBean an, weil Spring im Bereich der Konfiguration von Inbound JMS Resourceadaptern noch sehr wenig Unterstützung bereit stellt (erst ab Spring 2.1 wahrscheinlich). Das alles geht ziemlich elegant, problemlos und ist auch gut ohne Infrastruktur Testbar.
Vielleicht wirfst du auch einfach mal nen Blick auf die Referenzenseite von Spring. Das französische Onlinesteuersystem ist mit Spring implementiert, genauso wie Voca, ein riesiges Bankingsystem in England... ich glaub die hätten das nicht mit Spring gemacht, wenn die Technologie nicht ausgereift wäre.
Gruß
Ollie
@Tom: eigentlich sollten wir ne Evangelistprämie bei I21 beantragen
Ähnliche Themen
-
Beispiel zu Messaging mit MSMQ
Von Thomas Darimont im Forum .NET CaféAntworten: 2Letzter Beitrag: 06.09.10, 13:46 -
Instant Messaging / Chat in PHP (mit Ajax, Socket,...?)
Von deb_ugger im Forum PHPAntworten: 9Letzter Beitrag: 21.05.08, 15:38 -
JBossMQ Queue deployen
Von Daniel23 im Forum Enterprise Java (JEE, J2EE, Spring & Co.)Antworten: 3Letzter Beitrag: 19.05.08, 16:10 -
Google bietet neue Instant Messaging Lösung an
Von Thomas Darimont im Forum SmalltalkAntworten: 9Letzter Beitrag: 25.08.05, 22:34 -
Problem bei User-to-User-Messaging und "Re: Betreff"
Von ToddurchWendy im Forum PHPAntworten: 4Letzter Beitrag: 06.04.04, 12:39






Zitieren
Login





