Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC with JBoss vs Tomcat - Advantages / Practice

Okay. This is again a question of industry practice.

  • Tomcat = Web Container
  • JBoss, WebLogic, etc = Application Servers that have Web Container within (for JBoss, its forked Tomcat)

Spring does not need Application Server like JBoss. If we use enterprise services like JMS, etc we can use independent systems like RabbitMQ, ApacheMQ, etc.

  1. Question is why do people still use JBoss and other Application Serves for purely spring based applications?
  2. What are the advantages Spring can make use of, by using Application Servers? Like object pooling? What specific advantages does Application Server offers? How are those configured?
  3. If not for spring, for what other purposes Application Servers are used for Spring/Hibernate, etc stack? (Use cases)
like image 794
Kevin Rave Avatar asked Mar 07 '13 17:03

Kevin Rave


2 Answers

Actually I would say listening for JMS is probably the best reason for an application server. A stand alone message broker does not fix the problem since you still need a component that's listening for messages. The best way to do this is to use a MDB. In theory you can use Springs MessageListenerContainer. However this has several disadvantages like JMS only supports blocking reads and Spring therefore needs to spin up it's own threads which is totally unsupported (even in Tomcat) and can break transactions, security, naming (JNDI) and class loading (which in turn can break remoting). A JCA resource adapter is free to do whatever it wants including spinning up threads via WorkManager. Likely a database is used besides JMS (or another destination) at which point you need XA-transactions and JTA, in other words an application server. Yes you can patch this into servlet container but that this point it becomes indistinguishable from an application server.

IMHO the biggest reason against application servers is that it takes years after a spec is published (which in turn takes years as well) until severs implement the spec and have ironed out the worst bugs. Only now, right before EE 7 is about to be published do we have are EE 6 servers starting to appear that are not totally riddled with bugs. It gets comical to the point where some vendors do no longer fix bugs in their EE 6 line because they're already busy with the upcoming EE 7 line.

Edit

Long explanation of the last paragraph:

Java EE in a lot of places relies on what's called contextual information. Information that's not explicitly passed as an argument from the server/container to the application but implicitly "there". For example the current user for security checks. The current transaction or connection. The current application for looking up classes to lazily load code or deserialize objects. Or the current component (servlet, EJB, …) for doing JNDI look ups. All this information is in thread locals that the server/container sets before calling a component (servlet, EJB, …). If you create your own threads then the server/container doesn't know about them and all the features relying on this information don't work anymore. You might get away with this by just not using any of those features in threads you spawn.

Some links

http://www.oracle.com/technetwork/java/restrictions-142267.html#threads http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html#spring-4

If we check the Servlet 3.0 specification we find:

2.3.3.3 Asynchronous processing

Java Enterprise Edition features such as Section 15.2.2, “Web Application Environment” on page 15-174 and Section 15.3.1, “Propagation of Security Identity in EJBTM Calls” on page 15-176 are available only to threads executing the initial request or when the request is dispatched to the container via the AsyncContext.dispatch method. Java Enterprise Edition features may be available to other threads operating directly on the response object via the AsyncContext.start(Runnable) method.

This is about asynchronous processing but the same restrictions apply for custom threads.

public void start(Runnable r) - This method causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable. The container may propagate appropriate contextual information to the Runnable.

Again, asynchronous processing but the same restrictions apply for custom threads.

15.2.2  Web Application Environment

This type of servlet container should support this behavior when performed on threads created by the developer, but are not currently required to do so. Such a requirement will be added in the next version of this specification. Developers are cautioned that depending on this capability for application-created threads is not recommended, as it is non-portable.

Non-portable means it can may in one server but not in an other.

When you want do receive messages with JMS outside of an MDB you can use four methods on javax.jms.MessageConsumer:

  • #receiveNoWait() you can to this in a container thread, it doesn't block, but it's like peeking. If no message is present it just returns null. This isn't very well suited for listening to messages.
  • #receive(long) you can to this in a container thread, it does block. You generally don't wan't to do blocking waits in a container thread. Again not very well suited for listening to messages.
  • #receive(), this blocks possibly indefinitely. Again not very well suited for listening to messages.
  • #setMessageListener() this is what you want, your get a callback when a message arrives. However unless the library can hook into the application server this won't be a container thread. The hooks into the application server are only available via JCA to resource adapters.

So yes, it may work, but it's not guaranteed and there are a lot of things that may break.

like image 125
Philippe Marschall Avatar answered Sep 23 '22 08:09

Philippe Marschall


You are right that you don't really need a true application server (implementing all Java EE specs) to use Spring. The biggest reason people don't use true Java EE apps like JBoss is that then have been slow as #$@#% on cold start up time making development a pain (hot deploy still doesn't work that well).

You see there are two camps:

  • Java EE
  • Spring Framework.

One of the camps believes in the spec/committee process and the other believes in benevolent dictator / organic OSS process. Both have people with their "agendas".

Your probably not going to get a very good unbiased answer as these two camps are much like the Emacs vs VIM war.

Answer your questions w/ a Spring bias

  1. Because it in theory buys your less vendor lock-in (albeit I have found this to be the opposite).
  2. Spring's biggest advantage is AspectJ AOP. By far.
  3. I guess see Philippe's answer.

(start of rant)

Since @PhilippeMarschall defended Java EE I will say that I have done the Tomcat+RabbitMQ+Spring route and it works quite well. @PhilippeMarschall discussion is valid if you want proper JTA+JMS but with proper setup with Sprig AMQP and an a good transactional database like Postgresql this is less of an issue. Also he is incorrect about the message queue transactions not being bound/synchronized to the platform transactions as Spring supports this (and IMHO much more elegantly with @Transactional AOP). Also AMQP is just plain superior to JMS.

(end of rant)

like image 30
Adam Gent Avatar answered Sep 20 '22 08:09

Adam Gent