I'm just implementing a JavaEE assignment I was given on an interview.
I have some prior experience with EJB, but nothing related to JMS and MDBs. So here's what I find through the numerous examples:
application servers bind their topics and queues to different JNDI names - for example topic/queue, jms
the activationConfig property is required on JBoss, while in the Sun tutorial it is not.
after starting my application, jboss warns me that my topic isn't bound (it isn't actually - I haven't bound it, but I expect it to be bound automatically - in fact, in an example for JBoss 4.0 automatic binding does seem to happen). A suggested solution is to map it in some jboss files or even use jboss-specific annotations.
This might be just JBoss, but since it is certified to implement to spec, it appears the spec doesn't specify these these things. And there all the alleged portability vanishes.
So I wonder - how come it is claimed that JavaEE is portable and you can take an ear and deploy it on another application server and it magically runs, if such extremely basic things don't appear to be portable at all.
P.S. sorry for the rant, but I'm assume I might be doing/getting something wrong, so state your opinions.
Java EE, like (almost?) any standard, is something that implementers strive to advertise adherence to but desperately don't want to adhere to.
Consider this question: how does Red hat make money? By giving things away or by selling them? If the code you wrote could be easily transferred to another Java EE application server, this would interfere with them making money from you. The solution to this is the venerable "embrace and extend" technique that has been attributed to Microsoft but in reality has been the tool of choice for commercial software vendors since the first standard was published.
If you stick strictly to the Java EE APIs in your code then JBoss (or Geronimo (or JonAS (or ...))) will run it as well as any other compliant application server with the only changes being required in the server-specific deployment descriptors. This is the embrace stage.
Each server -- the commercial ones (like JBoss) in particular! -- also tends to add extra stuff to the API to "make things easier". (To be fair these often do make things easier.) Developers -- especially those not intimately familiar with the standard APIs -- frequently fall into the trap of relying on these extra APIs without wrapping them in any way, thus allowing these extensions to inundate their code to the point that they're difficult to remove should you wish to change platforms. This is the extend stage.
Name a standard from any point in software history and you'll find people embracing and extending (to the point that when people talk about "deadly embrace" I have to forcibly move my thoughts away from vendor lock-in problems to the proper terminology). You'll also find end-users (developer or otherwise) falling for it. Java EE is no different than any other technology in this regard.
Then you factor in just how badly-worded most specifications are and ...
Joel says "all non-trivial abstractions are, to some degree, leaky." I have found this to be very applicable to JavaEE. Consider that a JMS exception may be something transient such as a full queue. This is a typical fast-producer/slow-consumer problem and ideally the producer will throttle down to match the consumer's speed. But the error may also be fatal such as an authorization failure. In the first case retries eventually succeed (usually) whereas in the second case no amount of retry will help until humans intervene to fix the authorization failure.
So what do you do in your portable program to address this? One approach is to treat every JMS exception as fatal. Close all your objects and reinitialize the program. Sort of like killing a fly with a sledgehammer but very portable. Alternatively, you can check the JMS exception to see if it's a transient or fatal error and take some appropriate action. This is much more efficient but since the JMS exceptions are provider-specific it is hardly portable. Some of my clients have taken the approach of writing vendor-specific shims which catch JMS exceptions and do vendor-appropriate things with them so that the code can be "portable" (think: software equivalent of the Hardware Abstraction Layer).
And of course, this is just exception handling. Similar issues exist across the board. Consider reconnection details. Some transports bubble up a connection failure to the application or container. Some hide it away with the idea that the code should not need to know about this. But the reality is that virtually all messaging applications will need to provide an alert or log entry if the network is permanently down. You would not want the app to just hang forever if the network failed, right? So ultimately even an app running on a transport that provides transparent reconnect needs to code for connection failures. The specific features and behavior of the transport provider will leak up through the abstraction of JMS.
For my money, JavaEE makes the skills portable across transport providers. The application needs to be aware enough of the underlying transport provider to deal with the abstractions that bubble up to the surface. To the extent that you can avoid the leaks the app is portable, but no further.
That's just a partial answer but Java EE 6, more precisely EJB 3.1, finally specifies Portable Global JNDI Names. Prior to Java EE 6, JNDI naming wasn't standardized and each app server vendor was using its own rules which was indeed bad for portability (a kind of vendor lock in). Consequently, in the J2EE 1.4 world, if you wanted to ease the portability of your enterprise application it was necessary to implement various strategies, typically in your ServiceLocator class. The introduction of dependency injection in Java EE 5 reduced the need for lookups and somehow "improved" the portability but still, no standard for when JNDI lookups are needed and polyglot ServiceLocator are still required.
The core EE application can run unchanged. The external configuration is application server specific.
Related
I want to make some file operations (copy) in stateless EJB Method. I know about not recommndig to do it. But it could be possible for some special EJB implementation. What is the best thing for Wildfly ?
EDIT Some disturbing old links:
"Sun blueprint: EJB Restrictions"
EJB Bad Practices: Use of Java I/O
Stackoverflow
What is the best thing for Wildfly ?
Just doing the file operation (seriously). It's not as-if there's a security manager installed to prevent you from doing this.
And a stateless EJB is not different from many other types of methods in beans in Java EE. It's not the case, as some people think, that it's not allowed in EJB methods but is allowed in CDI bean methods. This is simply not the case.
There's some old information out there, where the spec said that "EJB was not allowed to". But what was actually meant is that Java EE was not allowed to. At the time EJB was seen as equivalent to Java EE, so that's the origin of this wide spread confusion.
Later this myth was starting a life of its own where people dreamed up scenarios where it was supposedly allowed to do IO in Servlets, but not from an EJB, so they designed all kinds of crazy architectures to delegate IO (or threading, another favorite) from an EJB to a Servlet. Absolutely ludicrous!
The restriction (as mentioned above, intended for the whole of Java EE, not just EJB) was also put in too eagerly. There's simply no reason to absolutely forbid it.
Some of the answers that you quote are more retroactive reasons. People just make up reasons for a rule to somehow justify their world, even though the reason and the rule don't match.
For this reason, the rule has been removed from the EJB spec.
That's right, in the current EJB spec you will not longer find that it's forbidden to use IO from an EJB (which, again, never meant to say "EJB", but should be read as "Java EE").
See:
https://blogs.oracle.com/marina/entry/ejb_3_2_news
https://blogs.oracle.com/arungupta/entry/what_s_new_in_ejb
Of course, as with many things, you may or may not have to be cautious when using IO, but this is completely unrelated to Java EE or EJB and holds for almost any application, and is more dependent on the kind of IO, the kind of application you're coding and your situation.
Two small extreme examples:
Your very own personal Java EE application of which you are the only developer that you installed at home on your raspberry pi and that reads a small configuration file at startup from an external location -> pretty much always okay.
Large clustered enterprise application being developed by many different teams, integrated separately, deployed separately, highly transactional that wants to write temporary data to a filesystem but that has to be cleanedup again when the transaction ends -> likely not such a good idea.
Between those two that are literally an infinite amount of variations. We had for example a larger enterprise application that did IO to an external folder from a Singleton in a very controlled and specific way. The app served millions of users under intense load and there was never a problem with the IO. So even "enterprise" and "transactional" do not necessarily have to mean "no IO". It really depends.
My question: What approach could/should I take to communicate between two or more JVM instances that are running locally?
Some description of the problem:
I am developing a system for a project that requires separate JVM instances to isolate certain tasks from each other entirely.
In it's running, the 'parent' JVM will create 'child' JVMs that it will expect to execute and then return results to it (in the format of relatively simple POJO classes, or perhaps structured XML data). These results should not be transferred using the SysErr/SysOut/SysIn pipes as the child may already use these as part of its running.
If a child JVM does not respond with results within a certain time, the parent JVM should be able to signal to the child to cease processing, or to kill the child process. Otherwise, the child JVM should exit normally at the end of completing its task.
Research so far:
I am aware there are a number of technologies that may be of use e.g....
Using Java's RMI library
Using sockets to transfer objects
Using distribution libraries such as Cajo, Hessian
...but am interested in hearing what approaches others may consider before pursuing one of these options, or any others.
Thanks for any help or advice on this!
Edits:
Quantity of data to transfer- relatively small, it will mostly be just a handful of POJOs containing strings that will represent the result of the child executing. If any solution would be inefficient on larger amounts of information, this is unlikely to be a problem in my system. The amount being transferred should be pretty static and so this does not have to be scalable.
Latency of transfer- not a critical concern in this case, although if any 'polling' of results is needed this should be able to be fairly frequent without significant overheads, so I can maintain a responsive GUI on top of this at a later time (e.g. progress bar)
Not directly an answer to your question, but a suggestion of an alternative.
Have you considered OSGI?
It lets you run java projects in complete isolation from each other, within the SAME jvm.
The beauty of it is that communication between projects is very easy with services (see Core Specifications PDF page 123). This way there is not "serialization" of any sort being done as the data and calls are all in the same jvm.
Furthermore all your requirements of quality of service (response time etc...) go away - you only have to worry about whether the service is UP or DOWN at the time you want to use it. And for that you have a really nice specification that does that for you called Declarative Services (See Enterprise Spec PDF page 141)
Sorry for the off-topic answer, but I thought some other people might consider this as an alternative.
Update
To answer your question about security, I have never considered such a scenario. I don't believe there is a way to enforce "memory" usage within OSGI.
However there is a way of communicating outside of JVM between different OSGI runtimes. It is called Remote Services (see Enterprise Spec PDF, page 7). They also have nice discussion there of the factors to take into consideration when doing something like that (see 13.1 Fallacies).
Folks at Apache Felix (implementation of OSGI) I think have implementation of this with iPOJO, called Distributed Services with iPOJO (their wrapper to make using services easier). I've never used this - so ignore me if I am wrong.
I'd use KryoNet with local sockets since it specialises heavily in serialisation and is quite lightweight (you also get Remote Method Invocation! I'm using it right now), but disable the socket disconnection timeout.
RMI basically works on the principle that you have a remote type and that the remote type implements an interface. This interface is shared. On your local machine, you bind the interface via the RMI library to code 'injected' in-memory from the RMI library, the result being that you have something that satisfies the interface but is able to communicate with the remote object.
akka is another option, as well as other java actor frameworks, it provides communication and other goodies derived from the actor model.
If you can't use stdin/stdout, then i'd go with sockets. You need some sort of serialization layer on top of the sockets (as you would with stdin/stdout), and RMI is a very easy to use and pretty effective such layer.
If you used RMI and found the performance wasn't good enough, i'd switch to some more efficient serializer - there are plenty of options.
I wouldn't go anywhere near web services or XML. That seems like a complete waste of time, likely take more effort and deliver less performance than RMI.
Not many people seem to like RMI any longer.
Options:
Web Services. e.g. http://cxf.apache.org
JMX. Now, this is really a means of using RMI under the table, but it would work.
Other IPC protocols; you cited Hessian
Roll-your-own using sockets, or even shared memory. (Open a mapped file in the parent, open it again in the child. You'd still need something for synchronization.)
Examples of note are Apache ant (which forks all sorts of Jvms for one purpose or another), Apache maven, and the open source variant of the Tanukisoft daemonization kit.
Personally, I'm very facile with web services, so that's the hammer which which I tend to turn things into nails. A typical JAX-WS+JAX-B or JAX-RS+JAX-B service is very little code with CXF, and manages all the data serialization and deserialization for me.
It was mentioned above, but i wanted to expand a bit on the JMX suggestion. we actually are doing pretty much exactly what you are planning to do (from what i can glean from your various comments). we landed on using jmx for a variety of reasons, a few of which i'll mention here. for one thing, jmx is all about management, so in general it is a perfect fit for what you want to do (especially if you already plan on having jmx services for other management tasks). any effort you put into jmx interfaces will do double duty as apis you can call using java management tools like jvisualvm. this leads to my next point, which is the most relevant to what you want. the new Attach API in jdk 6 and above is very sweet. it enables you to dynamically discover and communicate with running jvms. this allows, for example, for your "controller" process to crash and restart and re-find all the existing worker processes. this is the makings of a very robust system. it was mentioned above that jmx basically rmi under the hood, however, unlike using rmi directly, you don't need to manage all the connection details (e.g. dealing with unique ports, discoverability, etc). the attach api is a bit of a hidden gem in the jdk, as it isn't very well documented. when i was poking into this stuff initially, i didn't know the name of the api, so figuring how the "magic" in jvisualvm and jconsole worked was very difficult. finally, i came across an article like this one, which shows how to actually use the attach api dynamically in your own program.
Although it's designed for potentially remote communication between JVMs, I think you'll find that Netty works extremely well between local JVM instances as well.
It's probably the most performant / robust / widely supported library of its type for Java.
A lot is discussed above. But be it sockets, rmi, jms - there is a lof of dirty work involved.
I would ratter advice akka. It is a actor based model which communicate with each other using Messages.
The beauty is, the actors can be on same JVM or another (very little config) and akka takes care the rest for you. I haven't seen a more cleaner way than doing this :)
Try out jGroups if the data to be communicated is not huge.
How about http://code.google.com/p/protobuf/
It is lightweight.
As you mentioned you can obviously send the objects over the network but that is a costly thing not to mention start up a separate JVM.
Another approach if you just want to separate your different worlds inside one JVM is to load the classes with different classloaders. ClassA#CL1!=ClassA#CL2 if they are loaded by CL1 and CL2 as sibling classloaders.
To enable communications between classA#CL1 and classA#CL2 you could have three classloaders.
CL1 that loads process1
CL2 that loads process2 (same classes as in CL1)
CL3 that loads communication classes (POJOs and Service).
Now you let CL3 be the parent classloader of CL1 and CL2.
In classes loaded by CL3 you can have a light-weight communication send/receive functionality (send(Pojo)/receive(Pojo)) the POJOs between classes in CL1 and classes in CL2.
In CL3 you expose a static service that enables implementations from CL1 and CL2 register to send and receive the POJOs.
I'm currently in the research phase for a (very) small database application.
It's for a local charity which only has 3 or 4 client machines which will be running the system - however in order to move some extraneous logic away from the clients, I'm leaning toward using a three-tier architecture (there is data that is constantly read-through and updated when appropriate, that the client does not need to know about)
i.e. Client <-> Server logic <-> Database
Whilst I'm competent with Java itself and a few frameworks/libraries, I'm not particularly familiar with what frameworks could help me here. Obviously I'll be using JDBC for the database half, but the communication between client and server is the stumbling block at the moment - I don't really want to go anywhere near raw sockets, for example (overkill, or at least, another solution must exist)
I've asked a few developers I know about their opinions on what APIs to use, and whilst they've been very helpful, I'm still not too sure where to go. So far I've heard about RESTful stuff, SOAP, COBRA and a whole bunch of other technologies. SOAP is the main one that caught my attention (as there are some good examples of using it with normal applications rather than just with the web) but I'm still not sure where to go - it doesn't seem particularly appropriate for a general purpose app like this one (EJB also popped up but I heard a lot of hatred aimed at it - is this deserved?)
It feels as if in order to find out the 'best tool for the job' I actually need to learn each one in its entirety to 'get' them (which is obviously impractical)
Can anyone give me guidance as to how to choose APIs like these (when I haven't used them before) or give me information about a few common ones, or is it really just a case of experimenting with lots of them to see which fits best?
Or maybe I've totally missed the mark and there's a framework which is aimed at this exact situation with no obvious cons?
Thanks very much for any help.
EDIT:
Completely forgot to mention what it actually does: It isn't terribly complex - the charity runs a transport scheme, so it holds details of drivers, clients, driver mileage records etc. for viewing and editing The only real complexity comes with the drives, since drivers can be assigned to repeating (ongoing) drives that could foreseeably continue 'forever'. But each instance of an ongoing drive must be unique because they can be cancelled or edited individually
The main reason I'm angling for 3-tier is because being a charity (with many older volunteer computer users who aren't terribly 'savvy') I may well be updating the UI quite frequently to iron out bugs and bits that aren't very clear to novice users. So my plan is to get the backend between the server and DB absolutely 'bulletproof' first of all, and then pour all my focus onto the UI so I can continue to develop and iterate it without worrying about the backend (also since I will be developing pieces of it remotely, focusing updates on client side is slightly simpler)
All these attributes probably shout out 'do a web based system' - the snag here is that they're after all kinds of tricky integration with some applications they already run, which I'm not confident I can get done (properly) with a web app.
For the server itself, you'll need some sort of JavaEE server.
Common implementations here are GlassFish (the reference implementation) and Apache Tomcat... assuming you don't need anything more advanced than a Servlet container. Chances are you won't if you're just using web services.
For the client, I assume you're going to have a GUI application, presumably that uses Swing or SWF. You could also opt to make a web application, since you're already going to have a web server involved.
For client to server communications, you could use a JAX-WS (SOAP web services) or JAX-RS (RESTful services) implementation.
JAX-WS implementations include Sun's Metro (which ships as part of Java 6 SE) or Apache CXF.
JAX-RS implementations include Jersey and Apache CXF.
As for the database layer, JDBC isn't your only choice. Java also has the Java Persistence API (JPA, currently at version 2.0).
JPA is usually used in J2EE apps (web apps specifically) to simplify the Database layer. Common implementations are EclipseLink JPA (obsoletes Oracle TopLink) and Hibernate's Annotations.
All of these are based on various standards that make up JavaEE: Servlet 2.5, JAX-WS 2.0, JAX-RS 1.1, and JPA 2.0.
EJB also popped up but I heard a lot
of hatred aimed at it - is this
deserved?
It was fully deserved with versions 1 and 2 of the EJB spec. But EJB v3 represents a huge simplification that makes them outright pleasant to use. I can actually in good conscience recommend using entity beans instead of manual JDBC.
As for communications protocol, exposing EJBs as REST or SOAP services is absurdly simple in the newest EJB 3.1 spec - all it takes is adding a few annotations and you're set!
I wonder how is the best way to integrate Java modules developed as separate J(2)EE applications. Each of those modules exposes Java interfaces. The POJO entities (Hibernate) are being used along with those Java interfaces, there is no DTO objects. What would be the best way to integrate those modules i.e. one module calling the other module interface remotely?
I was thinking about: EJB3, Hessian, SOAP, JMS. there are pros and cons of each of the approaches.
Folks, what is your opinion or your experiences?
Having dabbled with a few of the remoting technologies and found them universally unfun I would now use Spring remoting as an abstraction from the implementation.
It allows you to concentrate on writing your functionality and let Spring handle the remote part with some config. you have the choice of several implementations (RMI, Spring's HTTP invoker, Hessian, Burlap and JMS). The abstraction means you can pick one implementation and simply swap it if your needs change.
See the SpringSource docs for more information.
The standard approach would be to use plain RMI between the various service components but this brings issues of sharing your Java interfaces and versioning changes to your domain model especially if you have lots of components using the same classes.
Are you really running each service in a separate VM? If these EJBs are always talking to each other then you're best off putting them into the same VM and avoiding any remote procedure calls as these services can use their LocalInterfaces.
The other thing that may bite you is using Hibernate POJOs. You may think that these are simple POJOs but behind the scenes Hibernate has been busy with CGLib trying to do things like allow lazy initialization. If these beans are serialzed and passed over remote boundaries then you may end up with odd Hibernate Exception getting thown. Personally I'd prefer to create simple DTOs or write the POJOs out as XML to pass between components. My colleagues would go one step further and write custom wire protocols for transferring the data for performance reasons.
Recently I have been using the MULE ESB to integrate various service components. It's quite nice as you can have a mix of RMI, sockets, web services etc without having to write most of the boiler plate code.
http://www.mulesource.org/display/COMMUNITY/Home
Why would you go with anything other than the simplest thing that works?
In your case that sounds like EJB3 or maybe JMS, depending on whether the communication needs to be synchronous or asynchronous.
EJB3 is by far these easiest being built on top of RMI with the container providing all the additional features you might need - security, transactions, etc. Presumably your POJOs are in a shared jar and therefore can simply be passed between your EJBs, although I tend towards passing value objects myself. The other benefit of EJB is, when done right, that it's the most performant (that's just my opinion btw ;-).
JMS is a little more involved, but not much and a system based on asynchronous communication affords certain niceties in terms of parallelizing tasks, etc.
The performance overhead of web-services, the inevitable extra config and additional points of failure make them, IMHO, not worth the hassle unless you've a requirement that mandates their use - I'm thinking interop with non-Java clients or providing data to external parties here.
If you need network communication between Java-only applications, Java RMI is the way to go. It has the best integration, most transparency and the least overhead.
If, however, some of your clients aren't Java-based, you should probably consider other options (Java RMI actually have an IIOP-dialect, which allows it to interact with CORBA, however - I wouldn't recommend doing this, unless it's for some legacy-code integration). Depending on your needs, webservices are probably your friend. If you are conserned with the networkload, you could go webservices over Hessian.
You literally mean remotely? As in running in a different environment with therefore different availability characteristics? With network overheads?
Assuming "yes" my first step would be to take a service approach, set aside the invocation technology for a moment. Just consider the design and meaning of your services. You know they are comparativley expensive to invoke, hence small busy interfaces tend to be a bad thing. You know that the service system might fail between invocations, so you may favour stateless services. You may need to retry requests after failure, so you may favour idempotent service designs.
Then consider availability relationships. Can your client work without the remote system. In some cases you simply can't progress if the remote system isn't available (eg. can't enable the employee if you can't get to the HR system) in other cases you can adopt a "fire-and-tell-me-later" philosophy; queue up the requests and process responses later.
Where there is an availability depdency, then simply exposing a synchronous interface seems to fit. You can do that with SLSB EJBs, if everything is Java EE, that works. I tend to generalise expecting that if my services are useful then non Java EE clients may want them too. So SOAP (or REST) tends to be useful. These days adding a web service interface to your SLSB is pretty trivial.
But my pet theory is that any sufficiently large IT system ends up needing aynch communications: you need to decouple the availability contraints. So I would tend to look for a JMS-style relationship. An MDB facade in front of your services, or SOAP/JMS is not too hard to do. Such an approach tends to highlight the failure-case design issues that were probably lurking anyway, JMS tends to make you think: "suppose I don't get an answer? suppose my answer comes late?"
I would go for SOAP.
JMS would be more efficient but you would need to code up an message driven bean for each interface.
SOAP on the other hand comes with lots of useful toolkits that will generate your message definition (WSDL) and all the neccesary handlers (client and server) when given an EJB.
With soap you can (but dont have to) deal with certificate security and secure connections over public networks. As the default protocol is HTTP over port 80 you will have minimal pain with firewalls etc. SOAP is also great for hetrogenious clients (in your case anything that isn't J2EE) with good support for most common languages on most common platforms.
I'm curious if there are any Java abstractions that are similar to .Net's AppDomain.
In particular, I'm curious because I've found that with our Coldfusion/J2EE server we need to restart it every few days due to a slow memory leak that we haven't been able to easily track down yet. This can wreck our long-running processes and we'd really like a way to slowly just push people to new JVMs as they age past a certain time period/memory threshold.
From my limited .Net experience I'm pretty sure that this is one situation that IIS and AppDomains are able to manage fairly seamlessly by recycling AppDomains that come under memory pressure. Please let me know if I'm way off on AppDomains helping in this scenario.
Any suggestions?
I think Yiannis's answer here is a little misleading. Simply saying "no, you can't" is not the whole story. The question is focused on unloading Java classes in a server process to remove leaky code from the JVM process without a process restart. The OP is not asking for the process-like memory isolation feature that an AppDomain gives, but the ability to unload classes in a running JVM. I say process-like, since under the hood an AppDomain is not a process, but enjoys some of the isolation aspects that a first-class process is afforded by the operating system. The isolate JSR mentioned is referring to this 'process-like' isolation. Unloading java ClassLoaders and thus classes, without cycling the OS process hosting the JVM is possible. A couple of methods are mentioned here: SO 148681. It is not trivial, or elegant to do this in Java, but it is possible.
Unfortunately, no.
The analogous concept in the Java world is the Isolate, that appeared first in the JSR 121. This was an API for a future JVM feature that would allow safe separation and communication between different applications running in the same JVM. After the JSR was published (around 2004) one research team in Sun worked in the Barcelona project. This project tried to implement the Isolation API in Sun's HotSpot 1.5 VM. After two years, they released a prototype for SPARC/Solaris. Windows/Linux versions were never released due to stability problems.
Recently, SUN has introduced a limited version of the Isolation API to J2ME, focusing of offering "multiple processes" in environments that didn't actively offer them. Recently, we also asked Sun for their status in implementing the Isolate API to standard JVMs and their response was that they plan to release a JVM with limited support. They plan to offer the ability to load/unload Isolates but without the ability to communicate between them.
Also, there has been an old reserach efford to build an Isolates-compatible JVM version, called JanosVM (java 1.1) but I doubt that it can be of any use today.
Hope this helps...
Recycling of individual JVMs on the basis of time or specific criteria such as growing memory consumption and memory use threholds is a capability of the advanced versions of the App Server I work with, WebSphere. If your App Server does not have that capability, then crafting some shell scripts to give something like that function should be doable.
This works quite nicely assuming:
a). Requests from users are sprayed around the a larger set of JVMs.
b). That all requests are stateless or there is some state replication capability. Replication is a capability of WebSphere and WebLogic, I'd guess that other app servers have the capability too.
In such environments there's no need to "slowly" move people to other servers. We just need to know that we can safely stop any one serve/JVM and that these sessions will pick up on another instance.