JBoss: hot deploy ain’t the same as restarting

I thought I ought to note this so I don’t forget.  I’m running JBoss 4.2.2. GA, and yesterday I hot-deployed a .war project that contained classes that JBoss also had (it was the activemq-core .jar, I think).  Anyway, the .war project hot-deployed ok and ran fine.  It wasn’t until I shut down JBoss and started it up again that the class loading problems manifested themselves.  This leads me to a rule of thumb:

Don’t consider the deployment testing complete until you’ve started JBoss with the deployment already in place.

If I hadn’t restarted JBoss when I did, I might have gone on to make other code changes, and the next time I restarted JBoss I would have seen the error and maybe attributed it to the new changes I had made… Eep!

I think I’m starting to understand why everyone around who has more experience with app servers than I do always seems to want to shut down JBoss before each new deployment, avoiding hot deploy.

Mainly a problem during development?

Hot deploy is probably not so problematic when you’re using stable, tested components.  I bet it’s mainly a problem during development, when all the dependencies haven’t been fully worked out yet.

Another interesting hot-deploy behavior: phantom consumers

I just changed my MessageListener to not propagate exceptions.  I hot-deployed my .war project to JBoss and used the ActiveMQ Console to send a message to the queue.  The JBoss console showed that the message was duly picked up by the newly updated messagelistener.  On a whim, I sent a second message to the queue.  This time, I got a stack trace on the JBoss console — the MessageListener had thrown an exception, the way it did before I made my most recent code change.  I looked in the ActiveMQ console and noticed that there were three consumers watching that queue, when normally there are two*.  It looked like JBoss still had the old MessageListener running in addition to the new one!  I restarted JBoss and the old exception-throwing MessageListener went away.

Update: The larger issue seems to be that the .war file is not cleanly undeploying (it leaves a consumer attached to the queue when it’s undeployed).

*I’m not sure why there seem to normally be two consumers and not one, watching the queue.  (Update 2: I found out why there were two.)


2 thoughts on “JBoss: hot deploy ain’t the same as restarting

  1. It looks like your app failed to de-register from the queue at shutdown. That’s the reason Servlets have init() and destroy() methods, and you have ContextListeners on later releases of the Servlet API.

    if you had used an EJB (that is, an MDB) the app server would be responsible for de-registering the MessageListener. I don’t know if the Spring framework has such a feature, maybe it’s a bug from Spring itself of your configuration is missing something.

    Most times a problem goes away with a restart it’s actually an application bug and not a hot-deploy issue. That is, I guess your application has a “Message Listener leak” just like most newbies create “JDBC Connection leaks” when they forget to insert a finnaly block calling close().

    The “standard practice” of restarting the app server is just a way to workaround those application buigs. Even when most app server administrators doen’t realize that.

  2. Actually it was that both my ContextLoaderListener and ServletContextListener were calling new ClassPathXmlApplicationContext("applicationContext.xml");, so the bean file was being loaded twice. After fixing my guard condition, I now only have one consumer, as I expected I should.

    Thanks for the input!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s