JMX - MBean automated registration on application deployment - java

I need some direction with JMX and Java EE.
I am aware (after few weeks of research) that the JMX specification is missing as far as deployment is concerned. There are few vendor specific implementations for what I am looking for but none are cross vendor. I would like to automate the deployment of MBeans and registration with the Server. I need the server to load and register my MBeand when the application is deployed and remove when the application is un-deployed.
I develop with:
NetBean 6.7.1, GlassFish 2.1, Java EE 5, EJB 3
More specific, I need a way to manage timer service runs. My application need to run different archiving agents and batch reporting. I was hoping the JMX will give me remote access to create and manage the timer services and enable the user to create his own schedule. If the JMX is auto registered on application deployment the user can immediately connect and manage the schedule.
On the other hand, how can an EJB connect/access an MBean?
Many thanks in advance.
Gadi.

I investigated JMX and EJB in Glassfish few years ago, so I don't remember all the details. But this might still help.
Glassfish-specific JMX. Glassfish has AMX and custom MBean can be deployed. AFAIK, such beans are meant to monitor the server itself, not to interact closely with a specific application. Such bean can be made persistent, and Glassfish will store their value somewhere across restart. Maybe have a look.
Registration and lookup. You can register MBean anytime from within an application using the MBeanPlatform, or MBeanServer. See this link, I don't remember exactly. You can also lookup other JMX bean and invoke operations on them. The names for the lookup are a bit crazy though. You can register the MBean when the app. starts from within a ServletContextListener.
Classloaders and deployment. The MBeans and the EJB instances are in distinct Classloader. I think you will need to place the .jar with the MBean implementation in the Glassfish deployment directory structure or add it the list of .jar in the classpath via the admin console. You can relatively easily manage to register a bean from within an EJB module, but a bean can not access a EJB easily, at least from my experience.
I managed to use plain JMX to expose statistics from my EJB application, and that worked relatively well. But I don't know if it's adequate to have something more interactive, as in your case where you want to have the EJB change their behavior depending the timer configured with JMX. I fear you will have troubles with this approach.
Hope it helps, despite the vagueness of what I remember.

Related

Spring JMX - Purpose of <context:mbean-server>

I am going through 'Chapter 20 - Managing Spring bean with JMX' from the book 'Spring In Action' 4th Edition by Craig Walls. There is one paragraph in this chapter on page 527.
From whence the MBean server?
As configured, MBeanExporter assumes that it’s running in an application server (such as Tomcat) or some other context that provides an MBean server. But if your Spring application will be running standalone or in a container that doesn’t provide an MBean server, you’ll want to configure an MBean server in the Spring context.
In XML configuration, the <context:mbean-server> element can handle that for you. In Java configuration, you’ll need to take a more direct approach and configure a bean of type MBeanServerFactoryBean() (which is what does for you in XML).
I have couple of questions on the above paragraph.
Does it mean that when we are running the application on server like Tomcat, <context:mbean-server> declaration is no longer required?
If above statement is true, who takes care of locating the MBean server when we are running on server like Tomcat or any other application server?
Thanks in advance!
That information is a little out of date...
or some other context that provides an MBean server.
Starting with Java 5 (if I recall correctly), the JVM has a built in MBeanServer. Prior to that, you had to be running in an App server, or provide some other MBeanServer such as mx4j.
Regardless, you still need the server bean declaration; it tells Spring which server to use (the underlying MBeanServerFactoryBean's locateExistingServerIfPossible is set to true by the XML namespace parser. If that flag is false, the factory bean would create an additional MBeanServer.

How to achieve clustering, load balancing and fail-over for Session Beans in OGS

JBoss seems to have a pretty easy set of annotations/configurations for clustering and load balancing session beans, but I'm not seeing the same features in the GlassFish 3.x docs.
Let's say I have both MyStatefulBean and MyStatelessBean beans. For both of them, I want the following capabilities:
I want to be able to create a cluster of the bean (to any number or scale) and put them behind a software load balancer that will round robin the beans; and
If 1 of the clustered beans fails for any reason I want it taken out of the pool
Does GlassFish free/(community edition) even support this or would I have to implement this myself?
Tangential to the first question: does clustering/load-balancing even make sense form stateful beans? I don't think it does now that I think of it...but still the question applies to both types of beans until proven otherwise!
First, you need to enable high availability for the application if you want to preserve the session state on failure. If using the admin console, there is a checkbox for this on the deploy app screen. If you are deploying from the command line, then use "asadmin deploy --availabilityenabled=true --target mycluster myapp.ear".
When the bean is looked up, the bean RMI proxy/stub that is generated has a list of all the clustered GlassFish instances that are available. The order of the servers is randomly generated, and the RMI stub will select the server at the top of the list. This is how the load is spread across the cluster. If the remote server fails, the next server in the list is selected. If the remote bean is a stateful session bean, then the session is preserved on failover.
As #pdudits mentions, please read the documentation on the subject for more in-depth coverage.
Hope this helps!
If you plan to invoke the beans via remote calls, this is the chapter in High Availability Guide you're looking for.
Failover of stateful beans makes sense, but load-balancing is also possible. Bear in mind that it has its limits, the greatest one being, that extended persistence context cannot be used.
The pool sizes for a bean is specified in EJB service settings and can be overrided in glassfish-ejb-jar.xml for specific bean
AFAIK this is what EJB Spec says - when a system exception occurs (this includes unchecked exceptions), the bean is destroyed.

JMX Remote Deployment Architecture

I'm reading up on JMX for the first time, and trying to see if its a feasible solution to a problem we're having on production.
We have an architecture that is constantly hitting a remote web service (managed by a different team on their own servers) and requesting data from it (we also cache from this service, but its a sticky problem where caching isn't extremely effective).
We'd like the ability to dynamically turn logging on/off at one specific point in the code, right before we hit the web service, where we can see the exact URLs/queries we're sending to the service. If we just blindly set a logging level and logged all web service requests, we'd have astronomically-large log files.
JMX seems to be the solution, where we control the logging in this section with a managed bean, and then can set that bean's state (setLoggingEnabled(boolean), etc.) remotely via some manager (probably just basic HTML adaptor).
My questions are all deployment-related:
If I write the MBean interface and impl, as well as the agent (which register MBeans and the HTML adaptor with the platform MBean server), do I compile, package & deploy those inside my main web application (WAR), or do they have to compile to their own, say, JAR and sit on the JVM beside my application?
We have a Dev, QA, Demo and Prod envrionment; is it possible to have 1 single HTML adaptor pointing to an MBean server which has different MBeans registered to it, 1 for each environment? It would be nice to have one URL to go to where you can manage beans in different environments
If the answer to my first question above is that the MBean interface, impl and agent all deploy inside your application, then is it possible to have your JMX-enabled application deployed on one server (say, Demo), but to monitor it from another server?
Thanks in advance!
How you package the MBeans is in great part a matter of portability. Will these specific services have any realistic usefulness outside the scope of this webapp ? If not, I would simply declare your webapp "JMX Manageable" and build it in. Otherwise, componentize the MBeans, put them in a jar, put the jar in the WEB-INF/lib and initialize them using a startup servlet configured in your web.xml.
For the single HTML adaptor, yes it is possible. Think of it as having Dev, QA, Demo and Prod MBeanServers, and then one Master MBeanServer. Your HTML Adaptor should render the master. Then you can use the OpenDMK cascading service to register cascades of Dev, QA, Demo and Prod in the Master. Now you will see all 5 MBeanServer's beans in the HTML adaptor display.
Does that answer your third question ?
JMX is a technology used for remote management of your application and for a situation for example when you want to change a configuration without a restart is the most proper use.
But in your case, I don't see why you would need JMX. For example if you use Log4j for your logging you could configure a file watchdog and just change logging to the lowest possible level. I.e. to debug. This does not require a restart and IMHO that should have been your initial design in the first place i.e. work arround loggers and levels. Right now, it is not clear what you mean and what happens with setLoggingEnable.
In any case, the managed bean is supposed to be deployed with your application and if you are using Spring you are in luck since it offers a really nice integration with JMX and you could deploy your spring beans as managed beans.
Finally when you connect to your process you will see the managed beans running for that JVM. So I am not sure what exactly you mean with point 2.
Anyway I hope this helps a little

DI in an EJB/MDB Application

I'm currently developing a small EJB application running on IBM Websphere Application Server 7 (Java EE 5). The app mainly consists of one MDB listening for incoming MQ messages which are transformed and stored in a DB. Currently I'm using a lot of Singleton/Factories to share configurations, mappings, datasource lookups etc. But this actually leads to some very hard to test code. The solution might be using a (simple) DI framework like guice/spring to inject the different instances. The question is: Where to place the initialization/ setup code? Where is the main entry point of the application? How can I inject instances into the MDBs?
it might be worth looking at backing off from using Guice, and trying to work with the injection mechanisms already available with Java EE 5.
Regarding finding a suitable "startup point", unfortunately the EJB specification does not define a way where you can have a bean run at startup. However, the web profile of the EE spec does have one -- you can add a WAR to your application, and set a servlet listener component:
http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html
You can set this to start whenever the application is loaded and started by the container (WebSphere). Watch out for classloader issues though.
Using Spring, you can do it via EJB3 interceptors, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ejb.html#ejb-implementation-ejb3
Useful info on caveats are in the javadoc, make sure you read it: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html

OC4J 10.1.3.4 problem with deploying multiple 2.1 EJBs

I am having troubles migrating from OC4J 10.1.2.3 to 10.1.3.1.4. The problem is for applications that have multiple EJBs (all are 2.1, no EJB 3.0). Jdeveloper will take the default ejb-jar.xml (the one required for Jdeveloper to run it on its stand-alone OC4J instance) and package it into each EJB JAR module NO MATTER what. This results in the app server drilling into each EJB JAR module when deploying, and find the same ejb-jar.xml file N times (where N = number of EJB Modules). This results in duplicate EJB references and will break any JNDI lookups such as: "java:comp/env/ejb/EJBName". Thus deploying an app that has 3 EJBs, EJB1, EJB2 and EJB3 causes the app server to register 9 EJBs instead of 3. I need a best practices way, but in between the way 10.1.3.4 and JDeveloper are acting the situation is rather dire...
Side note: They will work if the web app's JNDI look-up code is refractored to just "ejb/EJBName". This is not desirable though.
You should check the Oracle documentation to see which is your case.
The Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide is a good start
According to the Oracle® Containers for J2EE Services Guide, chapter 2: Using JNDI
when you use the form "ejb/EJBName" you perform "local" lookup. If you want to use the full form you must check the "Enabling Global JNDI Lookups" section of the "Using JNDI" chapter.
The problem was multiple reference in our deployment profiles. We were create a deployment profile for EACH EJB. This meant that each EJB had it's own ejb-jar.xml (this file contained a description of all EJBS in the project). Therefore, every time JDeveloper created an EJB, it placed a descriptor of all EJBS in each EJB it generated, causing an NxN amount of references. Therefore Nx(N-1) extra references.
Now, the key point is that Oracle Application Server 10.1.2.3.0 and bellow did not care about these duplicate references. However as we can see, 10.1.3.1.4 is a much different version and this did break.
Our fix: to have only 1 EJB Deployment profile that contains all of the EJB classes and the POJO's that they use. Remember, before there was 1 EJB Profile for each EJB... All this did was allow for Jdeveloper (which is crap IMHO) to correctly generate a valid EAR. A combination of Jdeveloper and Oracle's Application Server's crap is what caused this.

Categories

Resources