JMX Remote Deployment Architecture - java

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

Related

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.

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

JMX - MBean automated registration on application deployment

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.

How to auto create a JMS topic/queue on JBoss in a portable and per-application way?

It's simple: I have an MDB and an EJB that sends messages to a topic (or queue). JBoss complains that the topic is not bound to the JNDI context.
I want to have the topic/queue to be automatically created at best, or at least to have a standard way to define it, per application (say, in ejb-jar/META-INF)
this question and this blogpost show us how to do it in an application server specific way. This surely works, but:
I want to use the #MessageDriven annotation
I want the setting not to be global for the application server
I want the setting to be portable
It seems impossible to do this, with JavaEE 5 at least.

Best way to configure a Java enterprise application

I have a set of EJBs and other Java classes which need to be configured differently based on the system environment in which they are deployed: production, test, or lab. The configuration information includes stuff like URLs and database connection information.
We'd like to deploy the same exact product (EAR file) in each environment, and have the code then figure out where it is and what its configuration should be, without having to reach out to each deployment server in each environment to make changes.
What is the best way to configure all these components in a centralized, reliable, easy-to-maintain fashion?
Thanks for your thoughts.
The best, IMHO, is to use JNDI entries.
You may have to recode some parts of your application in order to use theses entries instead of plain vars, but with this setup:
Configuration is server-independant: each vendor provides its own implementation, but spec is a standard.
In a clustered environment, config can be persisted in a cluster-wide JNDI tree (see JBoss)
Configuration can be changed thru webadmin without restarting server.
How database connection pool information is stored / configured depends on the app server vendor. Put other variable stuff in property files on the classpath.
If you are deploying the exact same EAR to three different instances of a certain container than you will have to edit the deployment settings as there is no way that the deployment process could have any idea about which one of your three versions you would like to use at a particular deployment.
Deployment settings should go into JNDI entries as Piere-Yves said above.
If I were you, I would have my deployment-script (Ant?) properly populate the JNDI entries depending upon which environment you are deploying to.

Categories

Resources