ActivationConfig of MDB and ActivationSpec in WebSphere AS 7 - jms

I'm currently developing a small EJB 3 application for WebSphere AS 7 with WebSphere-MQSeries. It's a very simple app that mainly consists of one MDB listening on a queue, convert the incoming messages and write the extracted data into a db. I've finally got up it and running, but I'm a bit confused regarding ActivationConfig annotations in the code, the ibm-ejb-jar-bnd.xml and the activation spec in WAS itself. My main question is, why do I need ALL of them? Why should/could I specify things like the queue name or destinaton type via annotation (#ActivationConfigProperty) when I still need a activation spec in WAS where I also specify the destination e.g. Queue-Name? I addition I also need a binding via an xml file? Is that right? Is it also possible to specify the activationspec-name via annotation and thus get rid of the xml binding file? Can I avoid creating the activation spec in WAS?
Hope someone can clarify things, thanks.

You cannot avoid the Activation Spec entity because it is responsible to open connection to your JMS provider, query messages according to various options like the message selector filter.
According to WebSphere 7 InfoCenter EJB-3 annotations can replace activation specification properties from binding file but the properties required by WebSphere are not standard.
So as far as I know, you have to provide:
either the binding file, written manually or edited with the deployer tool
either at deployment setting properties in the administrative console or in automated jython/wsadmin script
Be aware that the Activation Spec is a runtime component that can be stopped, typically after some rollbacks on messages. In that case, it no longer consumes message and your MDB has nothing to process until you re-activate it from the WebSphere console.

Related

Why <amq:broker> is required?

I'm checking one project code; in spring.xml I see that 'amq:broker' is configured for input and output. Along with this configuration, ActiveMQConnectionFactory>PooledConnectionFactory>JmsConfiguration>ActiveMQComponent are also configured.
I need to know what is 'broker' element and why it is required and how it is different from 'brokerURL' of ActiveMQConnectionFactory.
'Broker' section of http://activemq.apache.org/ is little confusing :)
The broker declaration is needed if you want to run ActiveMQ embedded in your VM. You can use the connection factory as well to set up an embedded broker if you use the vm-transport, albeit this offers limited configuration options for the broker.
The connection factory you need to, well, create new connections to a broker. Independent of whether it is embedded or runs externally. For that the factory needs to know where to connect to and what transport to use.

WSO2 Identity Server - Custom JDBC User Store Manager - JDBC Pools

WSO2 Identity Server 5.0.0 (and some patches ;))
It does not appear that custom JDBC user store managers (child of JDBCUserStoreManager) use a JDBC pool. I'm noticing that I can end up session closed errors and sql exceptions whereas the Identity Server itself is still operating OK with its separate database connection (a configured pool).
So I guess I have two questions about this:
Somewhere up the chain, is there a JDBC pool for the JDBCUserStoreManager? If so, are there means to configure that guy more robustly?
Can I create another JDBC datasource in master-datasources.xml which my custom JDBC user store manage could reference?
Instead of using your own datasources/connections, you can import Carbon Datasources and use those (they come with inbuilt pooling and no need to worry about any configurations etc). You can either access these programmatically by directly calling ndatasource component or access them via JNDI.
To access them directly from ndatasource component:
The dependency:
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
<version>add_correct_version_here</version>
</dependency>
(You can check repository/components/plugins to find out the correct version for above dependency)
You can inject DataSourceService as in this code (the #scr.reference tag refers to the service you need to inject, this uses maven scr plugin to parse these dependencies when building the bundle).
Note that when you follow this approach you'll have to build the jar as an OSGi bundle as it uses declarative services (and have to place it in repository/components/dropins). Otherwise the dependencies won't be injected at runtime.
Next, you can access all the data sources as:
List<CarbonDataSource> dataSources = dataSourceService.getAllDataSources();
Rajeev's answer was really insightful and helped with investigating and evaluating what I should do. But, I didn't end up using that route. :)
I ended up looking through the Identity Server and Carbon source code and found out that the JDBCUserStoreManager does end up creating a JDBC pool configured by the properties you set for that manager. I had a class called CustomUserStoreConstants for my custom user store manager which had setMandatoryProperty called by default to set:
JDBCRealmConstants.DRIVER_NAME
JDBCRealmConstants.URL
JDBCRealmConstants.USER_NAME
JDBCRealmConstants.PASSWORD
So the pool was configured with these values, BUT that was it...nothing else. So no wonder it wasn't surviving the night!
It turned out that the code setting this up, if it found a value for the JDBCRealmConstants.DATASOURCE in the config params, it would just load up that datasource and ignore any other params set. Seeing that, I got rid of those 4 params listed above and forced my custom user store to only allow having a DATASOURCE and I set it in code with the default JNDI name that I would name that datasource always. With that, I was able to configure my JDBC pool for this datasource with all params such as testOnBorrow, validationQuery, validationInterval, etc in master-datasources.xml. Now the only thing that would ever need to change is the datasource's configuration in that file.
The other reason I went with the datasource in the master-datasources.xml is that I didn't have to decided in my custom user store's code which parameters I would want to have or not have and just manage it all in the xml file easily. This really has advantages with portability of configs and IT involvement for deployments and debugging. I already have other datasources in this file for the IS deployment.
All said, my user store is now living through the night and weekends. :)

glassfish 3.1.2 monitoring EJB container, bean-methods

the glassfish application server provides a nice monitoring REST interface.
To use it u can enable several monitorable items in the admin console, for example the EJB container. The documentation says, you can retreive EJB-statistics for every deployed application.
If you request a URL like localhost:4848/monitoring/domain1/server/applications/APPNAME/EJBNAME you will get statistics for a given EJB of the application.
Further, there is a possibility to look more deeply into each bean-method of the ejb, for example the executiontime, about which the documentation says:
"Time, in milliseconds, spent executing the method for the last successful/unsuccessful attempt to run the operation. This is collected for stateless and stateful session beans and entity beans if monitoring is enabled on the EJB container."
The problem now is, monitoring is enabled on the EJB-container (Level set to HIGH), but nothing is sampled in any bean-method in any EJB in any deployed application.
Is there something special to do in the bean and/or the glassfish ?
Thanks in advance for help,
Chris
EDIT:
Ok, I noticed something more about that behaviour:
In the server log you get a log message for each deployed EJB like that:
INFO: EJB5181:Portable JNDI names for EJB DataFetcher // ...
If I set the ejb-container monitoring level to HIGH (which is what I want to do), I get the following warning for each deployed EJB, regardless which app I deploy:
WARNING: MNTG0201:Flashlight listener registration failed for listener class : com.sun.ejb.monitoring.stats.StatelessSessionBeanStatsProvider , will retry later
I googled the warning but none of the resulst really help me enabling EJB monitoring...
This seems to be a Bug in Glassfish.
EJB Monitoring is currently not working in 3.1.2.
JIRA issue is already raised: http://java.net/jira/browse/GLASSFISH-19677
There is nothing "special" to do.
http://docs.oracle.com/cd/E18930_01/html/821-2431/abeea.html
For me it seems as if you probably enabled the monitoring option on the wrong configuration. Please double check.
To get rid of this message you can disable the monitoring on ejb container option below in the image
From Monitor Data--->Configure monitoring--->make ejb container log off

JMS message not getting added

I am facing a strange situation while using HornetQ.
My application architecture -
JMS provider : HornetQ (Standalone server, not used for anything else. I've created 2 queues on this server, say Q1 and Q2).
Producer : A web application deployed on a separate machine. This application creates instances of "ObjectMessage", passing a "Job" class instance as argument to the "ObjectMessage.setObject()" method and adds the message to Q1. Uses Spring JMS.
I also set a string property named "AGENT" in the message before adding it to the queue.
What's peculiar is that if I call ObjectMessage.setStringProperty("AGENT", null) or if I do not add the property to the message itself, the message does not get added to Q1. However, this does not happen on Q2, and I'm able to see the message in HornetQ's JMX console.
Is there some queue specific configuration that I should be looking out for?
Apologies for the loose wording - My team and I have been facing a tough time trying to fix this issue.
Thanks.
How are you creating the Producer? and How are you sending it?
It seems you're not committing on a transactional session?
I'm assuming you are using JMS, but I would need to see some code to help you in a better fashion. Usually the JBoss Forum is a better suitable place for discussions like this, since the SOF is not really a discussion forum.
I think the best would be you open a forum on JBoss (since it will be followed by a discussion) and provide the link here.

How to use JNI correctly with Java EE (Servlets) on windows?

I am trying to understand what is the correct way of usage JNI from Servlet.
As I understand there are several problems:
If native DLL crashes, it will bring down whole app server
If DLL is loaded by one class loaded, than another class loader won't be able to load and use it.
I searched internet and found couple of possible solution
Create standalone JMS enabled application and use JMS in Servlet to communicate with it.
Run standalone server, load in it JNI and talk to it through RMI
Use Java Connector architecture
I would appreciate any information on this subject, what is best practice in this case?
P.S. I am not sure whether it's important, but the application which needs to use native DLL runs on JBoss.
I would absolutely not run a JNI-based tool in a Java EE app server. Your suggestion for using JMS is a good one. You could create a service around message based Beans to respond to messages dispatched by your external service:
http://oreilly.com/catalog/entjbeans3/chapter/ch13.html
Here is the link to the Oracle Java EE documentation on Message-driven beans:
http://download.oracle.com/javaee/5/tutorial/doc/bnbpk.html
I would suggest getting two JBoss servers to talk to one another over JMS is easier than writing a JCA adapter, and that JMS message-driven beans are a cleaner interface. JCA doesn't seem to be evolving at all - there doesn't seem to be any great implementation tutorials (that's just my perception).

Resources