startup class (extends ServiceMBean) vs load-on-startup servlet - jboss

I am new to jboss and would like to know what are the differences between ServiceMBean and load-on-startup servlet tag in web.xml? Also, I would like to know which one will always get loaded first or they are loaded at the same time? In what situation, I should use MBean and when I should use startup servlet or it doesn't matter?
I need to write a a class/servlet to validate if all the required system properties (e.g -DINSTALL_DIR=blah ) is set. If not, then stop right there. else proceed and start the application.
Thanks in advance
-A

ServiceMBean is JMX, it is part of your JVM. load-on-startup servlet tag in web.xml is part of your J2EE application.
JMX is part of J2SE starting from JDK 1.5. So, you can have one ServiceMBean per JVM. not per application. JMX is used mostely for monitoring and managing the JVM. It provides access to information such as: number of classes loaded and threads running, memory consumption, garbage collection statistics, on-demand deadlock detection, and others. Another common use, is to refresh your cache.
JMX will allow you to instrument your application and control/monitor it using what-ever management console that your JMX container supports. An example would be a web application that implements a reference data cache...
A problem we had before was we would occasionally need to refresh the cache because a customer name changed in the database. If we had a refresh method on the MBean interface then we should be able to trigger this event using the JMX console. The JMX console may be a web or fat client that comes with our J2EE server. Our J2EE server may also support SNMP. This means that we may be able to invoke the method from a standard Tivoli or UniCenter console.
http://www.theserverside.com/news/1364664/J2EE-Application-Management-The-Power-of-JMX
You don't need remote access to ServiceMBean in order to trigger some asynchrious action. Moreover, you need validation on scope of application, not the whole JVM (while, you can, theoretically, handle this issue in the ServiceMBean). So, it is more naturally, to do it as load-on-startup servlet tag in web.xml. In this way, in every start up of your application validation will happen.
One more clarification: ServiceMBean is JBoss-way to write JMX. All MBeans are server wide (not application wide). That's why I use MBean and ServiceMBean freely above.

Related

Adding wildfly jms subsystem with wildfly cli java api without reloading the server

So we need to provision (add the jms extension/subsystem/configurations to standalone.xml) the JMS subsystem in wildfly when starting the server if it's not already provisioned and that needs to happen automatically. We have an application written in java and we chose to provision the jms subsystem with wildfly's cli java api and that is executed when our application starts deploying. The thing is we need to provision the jms subsystem and use it in the same application.
Problem is, when we add the needed configurations in standalone.xml with wildfly's cli java api, the server requires a reload but we can't reload it because our app is already deploying, it tries to use the defined queues and fails because... Well, the subsystem is not active yet. On next server restart everything is ok but as you can guess in a production environment this is unacceptable. Is there any solution to this? I've tried adding a reload cli command in the end of the batch that creates the jms subsystem and it starts reloading the server but the deployment doesn't stop and exceptions start flying left and right.
Also the whole idea of reloading the server from the app while the app is deploying seems kinda wrong to me.
Thanks in advance.
Solution:
Well the solution in the end was an easy one, we just had to add a reload step in the batch operation that adds the jms subsystem. The problem was that we had a set of async operation that all fired off when the app was deployed so i just had to make sure none of them started until i can check for the messaging subsystem and reload wildfly if necessary. That way I'm not interrupting any async tasks forcefully.
You need to select appropriate profile i.e full or full-ha while starting server only. If you do this there will not be need to add JMS subsystem.
If you want to go with your approach only, add dependency of queue in
application. It will not start deploying until and unless queue is bound to server.
we need to perform reload operation when we add new subsystem, if you dont want to perform reload operation then I will suggest you to start server in 'admin-only' mode. When we start server in 'admin-only' mode then it open only management port(9990/9999). Configure messaging subsystem through CLI command reload server instance. Hope it helps..!!

Jboss EAP 6 : HttpRequest http-header validation

As a security measure my organization requires me to validate a header attribute to allow a request to go through the business rules. Where would I need to configure this in the Jboss eap 6.3? This configuration was done before me and i am not sure how it was achieved before in the earlier jboss 5.x. Please let me know how would I configure the container security without making any application changes.
You could do this in a Global Valve, which is like a servlet filter but with more access to JBossWeb (Tomcat) internals and applies to all requests. Details are in the documentation at https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.4/html/Administration_and_Configuration_Guide/chap-Global_Valves.html
That is not portable between containers, and will not work in WildFly or EAP 7+ since the web container has changed from JBossWeb to Undertow.
In my understanding, this has to be done in applications. Not sure if this can be done generally in JBoss configuration.
Try this https://www.owasp.org/index.php/How_to_add_validation_logic_to_HttpServletRequest
Turns out we had a different way of handling it. We used the single sign on feature of Jboss 5 and at the container level validated the header. When the header was validated, a generic role name was exposed which was used by Applications to limit the resources to the specific role name.

Jboss EAR with EJB and webservice health monitoring and management

I am using Jboss5.1 and I have a EAR1 deployed which has a EJB3 component implemented using #Stateless annotation and the same EJB is also exposed as webservice using the annotation #webservice.
I want to check through a EJB service/management service bean(Packaged in another EAR2) from the start of deployment to un-deployment of EAR1 PERIODICALLY, if the EJB and Webservice is deployed and running properly and working normally and is not in deadlock/non responsive state.
I have looked into JMX and I am able to get notifications of create and destroy for EJB as well as webservice, but how to check periodically whether the EJB and webservice is working normally and is not in deadlock/non responsive state?
Also how to monitor Jboss ESB services?
Is the JMX is the only way or does jboss provides any other API's to do monitoring how about JBOSS MONITORING
Thanks in advance if you are looking at this.
Especially JBoss AS5.x is using the so called profile service (PS) as the main way to interact with the server. Unfortunately the PS is not JMX-based and on the other side you don't see all EJBs in the Platform MBean server.
RHQ has a plugin to monitor EJB instances inside AS5 as well as for other resource types like JBoss ESB or Apache Tomcat and is able to determine the availability of EJBs.
but how to check periodically whether the EJB and webservice is
working normally and is not in deadlock/non responsive state?
This is usually something that you can (only)(*) determine by hitting the relevant beans/methods and evaluating the outcome.
*) It may be possible to determine a bean in a deadlocked state by requesting a heap dump and looking for deadlocked periodically.

GlassFish 3.1.2 + Cluster + Web Container Properties

I have an issue in Glassfish regarding dealing with properties wehn setting up a web application We are moving from using Jetty to a clustered environment setup with GlassFish on Amazon AWS
Conventionally speaking when dealing with Servlets you are meant to use a .properties file when you want to parse in environment variables, however this causes issues when you use a distributed environment (you would have to place the .properties file in every cluster node). GlassFish has the ability to configure properties of the web container through their Admin Console, which means the properties would automatically distribute through the cluster
The problem is, I am getting random behavior regarding retrieving the variables. The first time I ran a test application, I couldn't retrieve the variables, however no it no longer works
Basically I am setting the environment variables through the admin UI. Under Configurations there are 3 configuration stetings, one for the cluster (usually named .config), one default-config and one server-config. Under Web Container, I have put a test property in all 3 of the called "someVal".
I then created a quick Scalatra app in Scala (which uses Servlet 2.5) and I used this line to attempt to get the properties
getServletContext.getInitParameter("someVal")
Any ideas what I am doing incorrectly, it always returns null?
Update
It appears what I was attempting to do isn't the "correct" way of doing things. So my question is, what is the standard way of providing specific application settings (outside of the .war and outside of runtime) when dealing with clusters in GlassFish. myfear stated that using a database is the standard approach, however I use these configuration settings themselves to define the JDBC connection
I got it. You are referring to the Web Container Settings
http://docs.oracle.com/cd/E18930_01/html/821-2431/abedw.html
I'm afraid that this never has been thought of as providing application specific configuration and I strongly believe that you will never be able to access those properties from the servlet context.
So, you could (should) use the servlet init params in web.xml if you are talking about application specific information. if you use
getServletContext().setInitParameter("param", "value");
you might be able to set them (at least for the runtime of the application). I'm not sure about cluster replication here. The normal way would be to have you configuration settings in the database.

JMS without JNDI?

We are running portlets in WebSphere 6.01, using Java 1.4. We want to send JMS messages to a JBoss 5 queue, running Java 5 (or maybe 6, but it's certainly newer than 1.4). Trying to connect using JNDI is not working, since we have to include the JBoss client jars in the classpath of the portlet, and they are Java 1.5. So I get an unsupported major/minor error when I try to create the InitialContext.
Can we connect straight to JBoss without using JNDI? Or is there some way to get around this issue I can't think of?
Even if you were able to connect to JMS without going through JBoss's JNDI, you would still need to include the JBoss client JAR in order to use JMS. Both JNDI and JMS are APIs, and you need the server's implementation of that client API in order to talk to the server.
If it's just your JNDI classes that prereq Java 5 and not the JBoss classes then you can do this. But you would have to set all of the properties of the objects and that is provider-specific. The WebSphere MQ JMS samples show how to do this with WMQ and you would need to know the property and value names for JBoss to make the equivalent code. Here is a code snippet from the WMQ JmsProducer.java sample:
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, host);
cf.setIntProperty(WMQConstants.WMQ_PORT, port);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName);
// Create JMS objects
connection = cf.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
if (isTopic) {
destination = session.createTopic(destinationName);
}
else {
destination = session.createQueue(destinationName);
}
producer = session.createProducer(destination);
On the other hand, if your JBoss classes prereq Java 1.5 then you need to run Java 1.5 or better.
Depending on the JBoss version you can directly instantiate all the JMS objects.
One particular version:
see http://www.jboss.org/file-access/default/members/jbossmessaging/freezone/docs/usermanual-2.0.0.beta1/html/using-jms.html
(Section 5.5. Directly instantiating JMS Resources without using JNDI)
I think JNDI is the only way that you can create JMS connection factories and destinations (queue or topic), and these are your means of communication.
In fact using JNDI is a way to be independant of the JMS provider, because you can easly change it.
But if you've got no problem with that most provider offer facilities to create a connection factory and destinations
It sounds like the problem isn't with JNDI but with the conflicting classnames between the environments.
You could try doing the classloading yourself when you try to instantiate the JBOSS client classes. That way you get a separate classloader from the one that loaded the Portlet. Just make sure you understand whether you need Parent-first or Parent-last behavior. Also on that page is debugging classloading which can show you how to set the Classpath for the classloader so you can isolate the JBOSS libraries and avoid classname collisions. It is a good resource for understanding even advanced classloading issues.