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

2 comments:

Montu said...

what is ms1??

Pierluigi Vernetto said...

ms1= managed server 1, the target server