Javaee - JBoss - Message Driven Bean

hss81

Grünschnabel
Hallo

ich entwickle gerade auf dem JBoss eine kleine Anwendung.
Sie hat eine Message Driven Bean die mit einer Session Bean kommuniziert.
Die Session Bean legt Einträge in einer MySql Datenbank an und liefert die Entity die sie angelegt hat wieder zurück an die MDB.
Die MDB schickt dann diesen Eintrag wieder zurück an den Client.

Das Problem was ich habe ist, das der JBoss 4.0.3SP1 die Thread nicht mehr abbaut.

Kann mit da einer weiter helfen?


Gruß
 
Heisst das,
1.dass die MDB immer neu Instantiiert wird, wenn ich sie vom Client aufrufe, d.h. x aufrufe x Threads?
2.Oder wird sie nur einmal im Server Instantiiert?

Der jBoss hat nach ca 10 Minuten 700 neue Threads offen. Ist nach meinem Gefühl ziemlich viel. Da sie ja nicht mehr abgebaut werden.
Anderst gefragt wann werden Threads auf dem AS gekillt?
 
Normalerweise konfigurierst du im AS eine Poolgröße für MDBs. Das ist je nach Hersteller unterschiedlich komfortabel oder besser gesagt unterschiedlich aufwändig ;). Die Defaultgrößen eines Pools liegen so zwischen 10 und 30 Stück.Manche AS erzeugen die MDBs dann bei Bedarf, andere wiederum ziehen gleich den kompletten Pool hoch und nutzen dann die Instanzen. Was aber definitiv nicht sein sollte, ist, das pro Request ein neuer Thread aufgemacht wird und der nie wieder zu geht.

700 Threads klingt etwas viel. Machst du irgendwo manuelles Threadhandling? Das klingt schon eher nach nem Bug...

REINHAUN!
 
Also ich mache keine manuelles Thread - Handling:

Evtl. liegt es an meiner MDB oder am aufruf des Clients.

Ich schnippel mal ein wenig Quelle Code zusammen. evtl liegt es ja an meinen Aurfufen. Vielleicht findest du ein wenig Zeit den Quelltext zu analysieren.

Danke im Voraus.
 
mein-service.xml:


Code:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Destination without a configured SecurityManager or without a SecurityConf 
     will default to role guest with read=true, write=true, create=false. -->

mbean code="org.jboss.mq.server.jmx.Queue"
  		name="jboss.mq.destination:service=Queue,name=meineQueue">
         		<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
	</mbean>


MDB:

Code:
@MessageDriven(activationConfig = {
		@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
		@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/meineQueue"),
		@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class MeineMDB implements MessageListener {
	
	private MessageDrivenContext ctx = null;


	@Resource(mappedName = "ConnectionFactory")
	QueueConnectionFactory clientReply;

	@EJB
	private IDataAccess iDataAccess;

	//private Transfer transferToClient = new Transfer();
	private Queue clientQueue;
	private String strProperty;
	
	 public void setMessageDrivenContext(MessageDrivenContext ctx)
	    throws EJBException {
	        this.ctx = ctx;
	    }

	
	public void ejbCreate(  ) {
        // no specific action required for message-driven beans
    }

     /** Required removal method for message-driven beans. */
    public void ejbRemove(  ) {
        ctx = null;
    }



	public void onMessage(Message clientMessage) {
		try {

			String strMessageFormat = clientMessage
					.getStringProperty("MessageFormat");
			clientQueue = (Queue) clientMessage.getJMSReplyTo();
			strProperty = strMessageFormat;

			// System.out.println(strMessageFormat);
			System.out.println(strProperty);
					

			if (strProperty.equals(IMessageProperty.SET_Entity)) {
				System.out.println("----------Set Entity------------");
				Transfer transferToClient = new Transfer();
				transferToClient.setEntity(this.iDataAccess
						.setEntity);

				transferToClient.setStatus(true);
				objectReplyToClient(clientQueue, strProperty, transferToClient);

			}
			
				
			
			
		} catch (Exception ex) {

			
			ex.printStackTrace();
		}finally{
			
		}
	}

	public void objectReplyToClient(Queue queue, String property,
			Serializable object) {
		try {
			Connection replyConnect = clientReply.createConnection();
			Session replySession = replyConnect.createSession(false,
					Session.AUTO_ACKNOWLEDGE);
			ObjectMessage oMessage = replySession.createObjectMessage();
			oMessage.setObject(object);
			oMessage.setStringProperty("MessageFormat", property);
			MessageProducer serverSender = replySession.createProducer(queue);
			serverSender.send(oMessage);
			serverSender.close();
			//replySession.close();
			
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	
	
}


ServerRequest - Klasse

Code:
public class ServerRequest {
	

	static ConnectionFactory serverConnectionFactory;

	static Context jndiContext;

	static Connection connectToServer;

	static Queue replyToClientQueue;
	
	
	public static Context getInitialContext(String serverAdresse,String port) throws NamingException {

		
		Properties p = new Properties();
		p.put(Context.INITIAL_CONTEXT_FACTORY,
				"org.jnp.interfaces.NamingContextFactory");
		p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
		p.put(Context.PROVIDER_URL, "jnp://localhost:1099");
		InitialContext c = new InitialContext(p);
		return c;
	}
	
	
	public static boolean initializeConnection() {

		try {

			jndiContext = getInitialContext("","");
			ConnectionFactory serverConnectionFactory =  (ConnectionFactory) jndiContext
					.lookup("ConnectionFactory");
		
			connectToServer = (org.jboss.mq.Connection) serverConnectionFactory.createConnection();
			
			connectToServer.start();
		
			Session session = connectToServer.createSession(false,SpySession.AUTO_ACKNOWLEDGE);
			
			replyToClientQueue = session.createTemporaryQueue();
			return true;
			
		} catch (NamingException e) {
			e.printStackTrace();
			return false;
		} catch (JMSException e) {
			e.printStackTrace();
			return false;
		} 
	}
	
	private MessageConsumer createListener(Connection connect, Queue replyToClient){
		ServerListener listener= new ServerListener();
		MessageConsumer clientConsumer = null;
		
		clientConsumer=listener.initialize(connect, replyToClient);
		
		return clientConsumer;
		
	}
	
	private void sendObjectMessage(String property, Serializable object){
		try {
			Session session = connectToServer.createSession(false,
					Session.AUTO_ACKNOWLEDGE);
			MessageProducer sendToServer = getServerRequestMP(session);
			ObjectMessage oMessage = session.createObjectMessage();
			oMessage.setObject(object);
			oMessage.setStringProperty("MessageFormat", property);
			
			
			oMessage.setJMSReplyTo(replyToClientQueue);
			createListener(connectToServer,replyToClientQueue);
			
			sendToServer.send(oMessage);
			//session.commit();
		//	session.close();
			
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
		
	private MessageProducer getServerRequestMP(Session session) {
		MessageProducer sendToServer = null;
		try {

			SpyQueue serverRequest = (SpyQueue) jndiContext
					.lookup("queue/meineQueue");
			sendToServer = session.createProducer((Destination)serverRequest);
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sendToServer;

	}
	
	
	public void setEntity(Entity entity){
		sendObjectMessageSR(IMessageProperty.SET_Entity, entity);
	}

}

ServerListener Klasse

Code:
public class ServerListener implements MessageListener {

	Session session;
	ServerListener k = this;
	
	MessageConsumer clientConsumer = null;
	public MessageConsumer initialize(Connection connect, Queue replyToClient) {
		
		try {			
			session = connect.createSession(false,
					Session.AUTO_ACKNOWLEDGE);

			clientConsumer = session.createConsumer(replyToClient);
			MessageListener listener = this;
			clientConsumer.setMessageListener(listener);
			

		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return clientConsumer;
	}

	@Override
	public void onMessage(Message message) {
		try {
			
			if (strMessageFormat.equals(IMessageProperty.SET_Entity)) {
				System.out.println("SET_Entity");
			//message.acknowledge();
			clientConsumer.close();
			
			//session.close();


		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
 
Ok .. nun kann ich das Problem eingegrenzt.

Es liegt nicht an der MDB sondern an den Session Bean.

Die Session Bean lebt ja so lange bis die Session geschlossen wird.

Frage: Öffne ich eine Session via Client indem ich die MDB aufrufe oder öffnet die MDB die Session, so dass ich die Session in der MDB schliessen muss?

Wie kann ich nun die Session schliessen
 
Interface

Code:
@Local
public interface  IDataAccess{

public EntityManager getEntityManager();
public Entity setEntity(Entity entity)
}



Code:
@Stateless
@Local(IDataAccess.class)
public class DataAccess implements IDataAccess {
  
@PersistenceContext(unitName = "XXXXXX")
	private EntityManager eM;

	public EntityManager getEntityManager() {
		// TODO Auto-generated method stub
		return this.eM;
		
	}

public setEntity(Entity entity){
eM.persist(entity);
eM.flush();
return entity
}



}

Muss ich evtl. das Interfase von SessionBean verwenden?
 

Neue Beiträge

Zurück