Lookup a Message Driven Bean via JNDI - glassfish

If I create a MessageDriven bean - is it available to other components in my app via JNDI? If so, how can I find/specify the name to look it up by? I'm deploying to glassfish if that makes any difference?

Assigning a JNDI name for an MDB is not required by Java EE specification (chapter 21.2.3 of EJB 3.0):
At the minimum, the EJB container must provide a JNDI API name space to the enterprise bean
instances. The EJB container must make the name space available to an instance when the instance invokes the javax.naming.InitialContext default (no-arg) constructor.
The business interfaces of other enterprise beans
[...]
MDBs don't qualify, as they don't have a business interface. Besides, since wiring up an MDB in another EJB/MDB would have little sense (what's your use case, BTW?), is probably skipped in Glassfish.
I've seen that WebLogic, for example allows that in its proprietary deployment descriptor, but I've never used it.

Related

Jboss 7 JNDI lookup class cast exception

I'm getting familiar with Jboss 7.
I'm writing some application to try out technologies.
So I wanted to have some simple monitoring service that will allow me to do some counter on business methods.
I wanted to access counters through jmx and jndi.
The 'counter service' is part of jmx bean. During jmx registration it is also registered in jndi context.
Then it is being used in some interceptors.
And here problem occurs, when I want to get reference from jndi I got class cast exception.
java.lang.ClassCastException: com.cybercom.pl.jbmon.SystemMonitorService cannot be cast to com.cybercom.pl.jbmon.SystemMonitorService
The reason for this i believe is that there classloaders are different.
During service startup it is:
ModuleClassLoader for Module "org.jboss.as.standalone:main" from local module loader #a4d593 ....
During execution it is:
ModuleClassLoader for Module "deployment.jboss-mon-app.ear.jboss-mon-web.war:main" from Service Module Loader
JMX beans, monitoring service and interceptor exists in same ejb module.
I finally did workaround for this, instead of going through jndi I used jmx client (https://github.com/michaljedryszka/jboss-sample-monitoring/commit/dcc4f05a4d6d50e592f0517bfe0454033f8e3659)
But still I don't know how to fix that CCE with jndi lookup.
What can You suggest?
Regards
You can try to create and install JBoss module with classes that are part of the JMX mbeans. This will cause to be loaded in same classloader for all access.
After you must add the dependency to the new module in the application, for example you can use jboss-deployment-structure.xml file.

Deploy Java EE application without starting

I am using Apache Geronimo. I need a way to deploy an EAR application on an application server without starting the EAR module automatically.
When I deploy my EAR, it is automatically started. I need a way to specify, that it should only be deployed but not started.
Is there a way to do this?
In the past I've opened and closed gates to certain EJBs with the use of JMX.
The cool part:
100% Control your beans from outside using JConsole or your own JMX client.
The drawback:
Every bean instance has to be registered in the MBean Server which is not that cool as you are usually having multiple instances of the same bean.
The solution to this topic was having a #Singleton EJB working as a MBean/controller for all the instances of one EJB.

Glassfish, EJB Load balancing

I'm having a problem with ejb load balancing inside glassfish 3 cluster.
I have one ear project witch contains EJB module and WEB module. All my EJB's are stateless and remote in EJB module. In WEB module I have one servlet which suppose to lookup for ejb and print on which instance in cluster he get ejb.
I'm calling EJB from servlet like this:
Properties props = System.getProperties();
props.setProperty("com.sun.appserv.iiop.endpoints", "10.8.10.202:23700,10.8.10.203:23700,10.8.10.204:23700,10.8.10.205:23700");
InitialContext ic = new InitialContext();
EJBRemote ejb = (EJBRemote) ic.lookup("java:global/app-name-ear/app-ejbs/EJB!com.tt.EJBRemote");
Problem is that my request always ends up on first instance of 4 possible.
How I can achieve load balancing in my case? Do I need stand alone client (web-app in separate project)? How glassfish cluster knows that there are another instances where my servlet can lookup for EJB?
Your issue is that you don't have enough load. and the way you look up EJBs is odd.
To look up remote EJB, rather than the properties in a servlet. but the CORBA / IIOP URL in the JNDI resources of the server. (in the admin console)
When you load balance, with IIOP each lookup binds to one instance and only switches to another instance for failover.
essentially you don't have enough load on the system to trigger the other instances of the EJB. Perhaps reduce the pool size to one to simulate high load.

Glassfish - How to broadcast JMS message to all instances in a cluster?

I am using Glassfish 3.1.2, and I set up a cluster with one node and two instances.
I have an message driven bean in my application that subscribes to a topic, which I deployed to the cluster.
When I publish a message to the topic I want both instances to receive the message.
However, in practice I am finding that only one instance receives the message.
I believe I am running into a feature called "shared subscriptions"
http://docs.oracle.com/cd/E18930_01/html/821-2438/gjzpg.html#MQAGgjzpg
The feature (which is enabled by default) says that beans in the cluster with the same client id are shared, and are effectively only one subscription.
It says that by default the client id of an MDB is its name, which means that both my instances are using the same client id.
So other than completely disabling this feature, I would like to know if it is possible to setup an MDB so that each instance subscribes with a different client ID? This seems a bit tricky since both instances are using the same WAR file. I think you can set the client ID in an annotation, but I'm not sure if that can be changed at runtime...
I'm not sure why you would completly disable this feature. In the link you provided, it states clearly that you configure this per ActivationSpec/MDB. So as far as I understand it, it would affect only the MDB you have at hand.
For an MDB, set the ActivationSpec property useSharedSubscriptionInClusteredContainer to false. Do this in exactly
the same way as with other ActivationSpec properties, using
annotations in the MDB itself or in the deployment descriptor
ejb-jar.xml or glassfish-ejb-jar.xml.
But you can of course set the client ID on a connection dynamically during runtime. Please note that you probably would have to handle the JMS connection yourself a bit more than relying on the features managed by the container.
http://docs.oracle.com/javaee/6/api/javax/jms/Connection.html#setClientID(java.lang.String)

WebSphere Application Server EJB Optimization

We are working on developing a Java EE based application. Our application is Java 1.5 compatible and will be deployed to WAS ND 6.1.0.21 with EBJ 3.0 and Web Services feature packs. The configuration is currently one cell with two clusters. Each cluster will have two nodes.
Our application, or our system, as I should rather say, comes in two or three parts.
Part 1: An ear deployed to one cluster that contains 3rd party vendor code combined with customization code. Their code is EJB 2.0 compliant and has a lot of Remote Home interfaces.
Part 2: An ear deployed to the same cluster as the first ear. This ear contains EBJ 3's that make calls into the EJB 2's supplied by the vendor and the custom code. These EJB 3's are used by the JSF UI also packaged with the EAR, and some of them are also exposed as web services (JAX-WS 2.0 with SOAP 1.2 compliance) for other clients.
Part 3: There may be other services that do not depend on our vendor/custom code app. These services will be EJB 3.0's and web services that are deployed to the other cluster.
Per a recommendation from some IBM staff on site here, communication between nodes in a cluster can be EJB RMI. But if we are going across clusters and/or other cells, then the communication should be web services.
That said, some of us are wondering about performance and optimizing communication for speed of our applications that will use our web services and EJB's. Right now most EJB's are exposed as remote. (and our vendor set theirs up that way, rather than also exposing local home interfaces). We are wondering if WAS does any optimizations between apps in the same node/cluster node space. If two apps are installed in the same area and they call each other via remote home interface, is WAS smart enough to make it a local home interface call?
Are their other optimization techniques? Should we consider them? Should we not? What are the costs/benefits? Here is the question from one of our team members as sent in their email:
The question is: Supposing we develop our EJBs as remote EJBs, where our UI controller code is talking to our EXT java services via EJB3...what are our options for performance optimization when both the EJB server and client are running in the same container?
As one point of reference, google has given me some oooooold websphere performance tuning documentation from 2000 that explains a tuning configuration you can set to enable Call By Reference for EJB communication when they're in the same application server JVM. It states the following:
Because EJBs are inherently location independent, they use a remote programming
model. Method parameters and return values are serialized over RMI-IIOP and returned
by value. This is the intrinsic RMI "Call By Value" model.
WebSphere provides the "No Local Copies" performance optimization for running EJBs
and clients (typically servlets) in the same application server JVM. The "No Local
Copies" option uses "Call By Reference" and does not create local proxies for called
objects when both the client and the remote object are in the same process. Depending
on your workload, this can result in a significant overhead savings.
Configure "No Local Copies" by adding the following two command line parameters to
the application server JVM:
* -Djavax.rmi.CORBA.UtilClass=com.ibm.CORBA.iiop.Util
* -Dcom.ibm.CORBA.iiop.noLocalCopies=true
CAUTION: The "No Local Copies" configuration option improves performance by
changing "Call By Value" to "Call By Reference" for clients and EJBs in the same JVM.
One side effect of this is that the Java object derived (non-primitive) method parameters
can actually be changed by the called enterprise bean. Consider Figure 16a:
Also, we will also be using Process Server 6.2 and WESB 6.2 as well in the future. Any ideas? recommendations?
Thanks
The only automatic optimization that can really be done for remote EJBs is if they are colocated (accessed from within the same JVM). In that case, the ORB will short-circuit some of the work that would otherwise be required if the request needed to go across the wire. There will still be some necessary ORB overhead including object serialization (unless you turn on noLocalCopies, with all the caveats it brings).
Alternatively, if you know that the UI controller is colocated, your method calls do not rely on parameter or return value copying, and your interface does not rely on the exception differences between local and remote views, then you could create and expose a local subinterface that will be much faster than remote access through the ORB.