Showing posts with label mdb. Show all posts
Showing posts with label mdb. Show all posts

Sunday, March 19, 2017

Suspending a MDB

It's easy to suspend consumption of JMS messages from a MDB with WLST (this code is from an Oracle Support document):
connect("username", "password", "t3://host:port")
domainRuntime()
cd("/ServerRuntimes/TargetServerName/ApplicationRuntimes/ApplicationDeploymentName/ComponentRuntimes/ApplicationDeploymentName/EJBRuntimes/MDBName_JNDINameoftheQueue")
cmo.suspend()


The Java JMX version is horrendously more complicated.

Here http://middlewaremagic.com/weblogic/?p=5099 they say:

“NOTE:Suspending One individual MDB from an EAR file is not possible so if your EAR application Contains multiple MDBs then you will have to suspend all the MDBs present in that EAR like above.”

but I am not really sure this is true, since there is a JMX method for this:

http://docs.oracle.com/cd/E23943_01/apirefs.1111/e13945/weblogic/management/runtime/MessageDrivenEJBRuntimeMBean.html#suspend()

However if you restart WLS, the MDB will resume consumption.

If you use native WLS JMS, you can disable consumption on the JMS queue itself. This feature doesn't seem to be available for foreign JMS destinations (like MQ). In this case, you can simply comment out the destination in the JMS WLS configuration XML.... the MDB at startup will complain that it can't connect to the destination, but the application will still deploy. It's a horrible hack but it works



Thursday, November 5, 2015

Limiting concurrent MDB pumping messages from a JMS (or MQ) queue (throttle)

you can use work managers with max-threads-constraint, or max-beans-in-free-pool : this is the ultimate source of truth... remember that by default you have only 16 concurrent beans registered as consumers on a queue:

https://docs.oracle.com/cd/E24329_01/web.1211/e24390/mdbtuning.htm#PERFM274



Friday, November 9, 2012

start-mdbs-with-application

http://docs.oracle.com/cd/E17904_01/web.1111/e15493/summary.htm


"Controls when MDBs start processing messages. When set totrue, an MDB starts processing messages as soon as it is deployed, even if WebLogic Server has not completed booting. This can cause an MDB application to access uninitialized services or applications during boot up and, therefore, to fail. Set to false to defer message processing until after WebLogic Server opens its listen port."

In OSB, a ProxyService consuming messages from a JMS queue is deployed as a MDB. Its weblogic-application.xml is:


<?xml version='1.0' encoding='UTF-8'?>
<web:weblogic-application xmlns:web="http://xmlns.oracle.com/weblogic/weblogic-application">
  <web:ejb>
    <web:start-mdbs-with-application>false</web:start-mdbs-with-application>
  </web:ejb>
  <web:application-param>
    <web:param-name>service-ref</web:param-name>
    <web:param-value>ProxyService$OSBProject$ProxyServices$MyJMSService</web:param-value>
  </web:application-param>
  <web:listener>
    <web:listener-class>com.bea.wli.sb.transports.jms.JmsEndPointAppListener</web:listener-class>
  </web:listener>
</web:weblogic-application>


The parameter is set to false for all the OSB JMS services.

Tuesday, November 6, 2012

Useful tips to configure MDBs and EJBs

http://technology.amis.nl/2012/02/24/ejb-an-mdb-best-practices-on-weblogic/

 most relevant for me:

  • home-is-clusterable in weblogic-ejb-jar.xml and set in on “true”
  • MDB listeners set setting start-mdbs-with-application to false in weblogic-ejb-jar.xml or weblogic-application.xml  (to ensure that consumpion of messages starts only after all JCA stuff is deployed)
  • check max-messages-in-transaction element in weblogic-ejb-jar.xml deployment descriptor



Tuesday, May 1, 2012

OSB Message Driven EJBs and Stateless EJB

You can expect to find these MDBs in a OSB server:

Email Transport Provider PolledMessageListenerMDBEJB_jmsResources!wlsb.internal.transport.task.queue.email_auto_1

File Transport Provider PolledMessageListenerMDBEJB_jmsResources!wlsb.internal.transport.task.queue.file_auto_1

Ftp Transport Provider PolledMessageListenerMDBEJB_jmsResources!wlsb.internal.transport.task.queue.ftp_auto_1

JMS Reporting Provider ReportingMDB_jmsResources!wli.reporting.jmsprovider.queue_auto_1 Message Driven EJB
Message Reporting Purger PurgingMDB_wli.reporting.purge.queue

SFTP Transport Provider PolledMessageListenerMDBEJB_jmsResources!wlsb.internal.transport.task.queue.sftp_auto_1

plus a MDB for each JMS-based ProxyService, but its format can be horrifying:

_ALSB_1333581925704 RequestEJB-7851583836778691984-57e93bc6.1367f6d8854.-7fc2_ACMEJMSModule!ACMECommonJmsServer1@ACMEQueue

(the recipe could be: strip away from the name whatever precedes the "_" sign)


The Stateless EJB are:

ALSB Test Framework TestService
SB Transport Provider SBDispatcher

Thursday, April 19, 2012

Deployment descriptors of a OSB MDB

Inside the /opt/oracle/domains/osbdv2do/sbgen/_ALSB_1329599716508.ear you will find:

META-INF/application.xml

<?xml version='1.0' encoding='UTF-8'?>
<jav:application xmlns:jav="http://java.sun.com/xml/ns/javaee">
  <jav:display-name>ProxyService GM_ReqPackMat/ProxyServices/ReqPackMat_ReqPackMatQ_to_WMOS_PS</jav:display-name>
  <jav:module>
    <jav:ejb>ejb.jar</jav:ejb>
  </jav:module>
</jav:application>


META-INF/weblogic-application.xml

<?xml version='1.0' encoding='UTF-8'?>
<web:weblogic-application xmlns:web="http://xmlns.oracle.com/weblogic/weblogic-application">
  <web:ejb>
    <web:start-mdbs-with-application>false</web:start-mdbs-with-application>
  </web:ejb>
  <web:application-param>
    <web:param-name>service-ref</web:param-name>
    <web:param-value>ProxyService$GM_ReqPackMat$ProxyServices$ReqPackMat_ReqPackMatQ_to_WMOS_PS</web:param-value>
  </web:application-param>
  <web:listener>
    <web:listener-class>com.bea.wli.sb.transports.jms.JmsEndPointAppListener</web:listener-class>
  </web:listener>
</web:weblogic-application>


The plan.xml in /opt/oracle/domains/osbdv2do/osb/config/plan/Plan-_ALSB_1335183510889.ear.xml is:

<?xml version='1.0' encoding='UTF-8'?>
<deployment-plan xmlns="http://xmlns.oracle.com/weblogic/deployment-plan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/deployment-plan http://xmlns.oracle.com/weblogic/deployment-plan/1.0/deployment-plan.xsd">
  <application-name>_ALSB_1335183510889</application-name>
  <module-override>
    <module-name>_ALSB_1335183510889.ear</module-name>
    <module-type>ear</module-type>
    <module-descriptor external="false">
      <root-element>weblogic-application</root-element>
      <uri>META-INF/weblogic-application.xml</uri>
    </module-descriptor>
    <module-descriptor external="false">
      <root-element>application</root-element>
      <uri>META-INF/application.xml</uri>
    </module-descriptor>
    <module-descriptor external="true">
      <root-element>wldf-resource</root-element>
      <uri>META-INF/weblogic-diagnostics.xml</uri>
    </module-descriptor>
  </module-override>
  <module-override>
    <module-name>ejb.jar</module-name>
    <module-type>ejb</module-type>
    <module-descriptor external="false">
      <root-element>weblogic-ejb-jar</root-element>
      <uri>META-INF/weblogic-ejb-jar.xml</uri>
    </module-descriptor>
    <module-descriptor external="false">
      <root-element>ejb-jar</root-element>
      <uri>META-INF/ejb-jar.xml</uri>
    </module-descriptor>
  </module-override>
  <config-root>/opt/oracle/domains/osbdv2do/osb/config/plan</config-root>
</deployment-plan>


And in the ejb.jar you can find:

META-INF/ejb-jar.xml

<?xml version='1.0' encoding='UTF-8'?>
<jav:ejb-jar xmlns:jav="http://java.sun.com/xml/ns/javaee">
  <jav:display-name>BEA ALSB JMS Inbound Endpoint</jav:display-name>
  <jav:enterprise-beans>
    <jav:message-driven>
      <jav:display-name>BEA ALSB JMS Inbound Endpoint (Request)</jav:display-name>
      <jav:ejb-name>RequestEJB-2972318866359532858-249b028e.136ddc2e3c6.-7fb5</jav:ejb-name>
      <jav:ejb-class>com.bea.wli.sb.transports.jms.JmsInboundMDB</jav:ejb-class>
      <jav:transaction-type>Container</jav:transaction-type>
      <jav:message-destination-type>javax.jms.Queue</jav:message-destination-type>
      <jav:env-entry>
        <jav:env-entry-name>service-ref</jav:env-entry-name>
        <jav:env-entry-type>java.lang.String</jav:env-entry-type>
        <jav:env-entry-value>ProxyService$PVReadStockDownloadErrorQueue$PVReadStockDownloadErrorQueue_PS</jav:env-entry-value>
      </jav:env-entry>
      <jav:env-entry>
        <jav:env-entry-name>XA-supported</jav:env-entry-name>
        <jav:env-entry-type>java.lang.Boolean</jav:env-entry-type>
        <jav:env-entry-value>true</jav:env-entry-value>
      </jav:env-entry>
      <jav:env-entry>
        <jav:env-entry-name>checksum</jav:env-entry-name>
        <jav:env-entry-type>java.lang.Integer</jav:env-entry-type>
        <jav:env-entry-value>-2061456480</jav:env-entry-value>
      </jav:env-entry>
    </jav:message-driven>
  </jav:enterprise-beans>
  <jav:assembly-descriptor>
    <jav:container-transaction>
      <jav:method>
        <jav:ejb-name>RequestEJB-2972318866359532858-249b028e.136ddc2e3c6.-7fb5</jav:ejb-name>
        <jav:method-name>*</jav:method-name>
      </jav:method>
      <jav:trans-attribute>Required</jav:trans-attribute>
    </jav:container-transaction>
  </jav:assembly-descriptor>
</jav:ejb-jar>

weblogic-ejb-jar.xml



  
    RequestEJB-2972318866359532858-249b028e.136ddc2e3c6.-7fb5
    
      
        1000
        1
      
      jms.jndi.dq.GM_StockDownload.StockDownloadReprocessQ
      t3://myhost.acme.com:8245
      weblogic.jms.XAConnectionFactory
    
    
      600
    
    
      jms/ConnectionFactory
      weblogic.jms.XAConnectionFactory
    
    
      jms/QueueName
      jms.jndi.dq.GM_StockDownload.StockDownloadReprocessQ
    
  
  BEA-010001
  BEA-010054
  BEA-010200
  BEA-010202




Hyperic will discover this MDB as "Weblogic 10.3 Message Driven EJB"

Weblogic osbdv1do osbdv1ms1 _ALSB_1335183510889 RequestEJB-6533237974024524838-be3fafc.135ee630c77.-7f0a_GM_ReqPackMatJMSModule!AcmeCommonJmsServer1@ReqPackMatQ Message Driven EJB

but also as a "Weblogic 10.3 Application"
Weblogic osbdv2do osbdv2ms1 _ALSB_1335183510889 Application


http://www.javamonamour.org/2012/04/wlst-browsing-deployed-applications.html

http://www.javamonamour.org/2011/10/osb-how-mdb-proxy-service-in.html

Thursday, March 24, 2011

MDB message selector with @ActivationConfigProperty annotation

for the MDB:

@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName="messagingType", propertyValue="javax.jms.MessageListener"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/YOURQUEUENAME"),
@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "MESSAGE_TYPE = 'MESSAGE_TYPE_IMPORT_BLA'")
},
mappedName = "YOURMDBNAME")




and in your code when you produce the Message:

TextMessage message = session.createTextMessage();
message.setText(messageText);
message.setStringProperty("MESSAGE_TYPE", "MESSAGE_TYPE_IMPORT_BLA");


(you can use an enum for message types...)

Wednesday, March 16, 2011

Minimalistic MDB on JBoss

http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Message_Driven_Beans.html


import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.log4j.Logger;

@MessageDriven(activationConfig = { 
       @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
       @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue")
     }, 
     mappedName = "ejb/MyMDB")
     
public class MyMDB implements MessageListener {
 final static Logger logger = Logger.getLogger(MyMDB.class);
 
 public void onMessage(Message paramMessage) {
  TextMessage tm = (TextMessage)paramMessage;
        try {
   String text = tm.getText();
   logger.info("received JMS message" + text);
  } catch (JMSException e) {
   logger.error("unable to read jms message", e);
   
  }
        
  
 }

}


Monday, August 23, 2010

How to create a MDB

I am writing down all the steps so I don't forget again:

(ms1 means Managed Server 1)

PLEASE ACTIVATE CHANGES AFTER EACH OPERATION

create a Persistent Store MQGEOFileStore, target it on MS1.
create a MQGEOJMSServer, back it up with the MQGEOFileStore, target it on MS1.
create a MQGEOSystemModule, target it to MS1.
inside it create a MQGEOSubDeployment, and target it to MQGEOJMSServer.

create also a MQGEOConnectionFactory with JNDI name MQGEOConnectionFactory, and use for it the MQGEOSubDeployment (click on Advanced targeting)... remember to make it "XA Connection Factory Enabled"
and a MQGEOQueue, JNDI name MQGEOQueue, and use MQGEOSubDeployment

This is the WLST Python (it's not included the "XA Connection Factory Enabled"):

cd('/')
cmo.createFileStore('MQGEOFileStore')

cd('/FileStores/MQGEOFileStore')
set('Targets',jarray.array([ObjectName('com.bea:Name=dev2WlsCBMs1,Type=Server')], ObjectName))

cd('/')
cmo.createJMSServer('MQGEOJMSServer')

cd('/Deployments/MQGEOJMSServer')
cmo.setPersistentStore(getMBean('/FileStores/MQGEOFileStore'))
set('Targets',jarray.array([ObjectName('com.bea:Name=dev2WlsCBMs1,Type=Server')], ObjectName))

cd('/')
cmo.createJMSSystemResource('MQGEOSystemModule')

cd('/SystemResources/MQGEOSystemModule')
set('Targets',jarray.array([ObjectName('com.bea:Name=dev2WlsCBMs1,Type=Server')], ObjectName))
cmo.createSubDeployment('MQGEOSubDeployment')

cd('/SystemResources/MQGEOSystemModule/SubDeployments/MQGEOSubDeployment')
set('Targets',jarray.array([ObjectName('com.bea:Name=MQGEOJMSServer,Type=JMSServer')], ObjectName))

cd('/JMSSystemResources/MQGEOSystemModule/JMSResource/MQGEOSystemModule')
cmo.createConnectionFactory('MQGEOConnectionFactory')

cd('/JMSSystemResources/MQGEOSystemModule/JMSResource/MQGEOSystemModule/ConnectionFactories/MQGEOConnectionFactory')
cmo.setJNDIName('MQGEOConnectionFactory')

cd('/JMSSystemResources/MQGEOSystemModule/JMSResource/MQGEOSystemModule/ConnectionFactories/MQGEOConnectionFactory/SecurityParams/MQGEOConnectionFactory')
cmo.setAttachJMSXUserId(false)

cd('/SystemResources/MQGEOSystemModule/SubDeployments/MQGEOSubDeployment')
set('Targets',jarray.array([ObjectName('com.bea:Name=MQGEOJMSServer,Type=JMSServer')], ObjectName))

cd('/JMSSystemResources/MQGEOSystemModule/JMSResource/MQGEOSystemModule/ConnectionFactories/MQGEOConnectionFactory')
cmo.setSubDeploymentName('MQGEOSubDeployment')

cd('/JMSSystemResources/MQGEOSystemModule/JMSResource/MQGEOSystemModule')
cmo.createQueue('MQGEOQueue')

cd('/JMSSystemResources/MQGEOSystemModule/JMSResource/MQGEOSystemModule/Queues/MQGEOQueue')
cmo.setJNDIName('MQGEOQueue')
cmo.setSubDeploymentName('MQGEOSubDeployment')

cd('/SystemResources/MQGEOSystemModule/SubDeployments/MQGEOSubDeployment')
set('Targets',jarray.array([ObjectName('com.bea:Name=MQGEOJMSServer,Type=JMSServer')], ObjectName))

activate()



For the MDB, it should start like this:

@MessageDriven(
 activationConfig = { @ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "MQGEOConnectionFactory"),     
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"
  ) }, 
 mappedName = "MQGEOQueue")

public class MQGeoFeedMDB implements MessageListener {
public void onMessage(Message message) {
     TextMessage tm = (TextMessage)message;
        String text = tm.getText();
.......
}




and, last but not least, the DD:



 
 
  MQGeoFeedMDB
  
   MQGEOQueue
   MQGEOConnectionFactory
  
 





Funnily, these operations succeed on my standalone Admin, but they fail on a proper domain with an Admin and a cluster....the error is:

one or more registered update listeners reported activation problems. The following failures occurred: -- The following failures occurred: -- weblogic.management.DeploymentException:
This probably because I didn't activate changes after each operation....WL doesn't execute oeprations in the right order....


and in the logs I find
Failed to start JMS Server "MQGEOJMSS
erver" due to weblogic.management.DeploymentException: The persistent store "MQGEOFileStore" does not exist.


and
[Store:280044]The file store directory "/acme/domains/dev2OsbCBDomain/servers/dev2OsbCBAdmin/data/store/MQGEOFileStore" does not exist.


I do a /acme/domains/dev2OsbCBDomain/servers/dev2OsbCBAdmin/data/store/MQGEOFileStore
to fix the problem.

Actually at the end I had to remove the target for MQGEOSystemModule and let the subdeployment take care of targetting.... Houston, these targetting with Subdeployment still have big problems.
I still get a message:
MDB application MQParserEARfromlocalJMSQueue is NOT connected to messaging system.


Reading in the logs I find:

The Message-Driven EJB: MQGeoFeedMDB is unable to connect to the JMS destination: MQGEOQueue. The Error was:
[EJB:015027]The Message-Driven EJB is transactional but JMS connection factory referenced by the JNDI name: MQGEOConnectionFactory is not a JMS XA connection factory.


On the whole, my impression is that

1) WebLogic error messages related to the JMS module are very poorly done, the error message appearing on the Console tells nothing about the root cause of the problem

2) Subdeployments have been poorly engineered, they still overlap with traditional targetting and they are not completely alternative to it, nor they can be completely replaced with traditional targeting...

3) When you perform several operations without activating, WebLogic should be smart enough to perform the activation activities in the proper order, without obliging you to perform an operation at a time and activate it.

3A) We really miss in WebLogic the ability to execute WLST code directly from the console, without having to run weblogic.WLST from a shell; and the ability to export objects as WLST script, in order to import them into another domain. Right now the only option is copy/paste sections of config.xml, which stinks.

4) but all of the above is a good news, it means that there is room for improvement