Hello. This may be a bit of a newbie question and is really just general J2EE (not JBoss specific) but I was hoping I could get some suggestions here.
I was wondering, in a J2EE architecture where _should_ I do things that are not request driven. For instance if I wanted to cache some items at server start up, or if I wanted to initialize and start a scheduler at start up (keeping in mind that I'm trying to be server agnostic so that my application can work on any of the major App servers) where would I do this.
I could start up a separate java app and have it make rmt calls into the app server to get the balls rolling so to speak. Or I could write a Static class that I start which in turn would start the server (with a static call to org.jboss.Main) but I don't like that option particularly. The MBeans (JMX) looked interesting but didn't look quite like they were meant for what I'm trying to do (looked more like a replacement for smnp). I _thought_ there was a way to tell an app server (like tomcat that supports servlets) to init a minimum number of servlet instances at start up (which would serve my purposes) but I'm beginning to think either I dreamed that up in my own head or it was a feature of one version of one server at one time.
Any thoughts or suggestions would be very much appreciated.
Thanks for the reply!
Actually, that is exactly what I ended up doing. One of the problems I was having though, is that I didn't know about the "'load-on-startup' in the servlet section of your servlet in web.xml" at the time.
Here's some more of the details that I found out regarding this attribute in case it helps anyone else (it's a snip from a post to another board):
"I was able to find the following in Chapter 13 of the Servlet Specification pertaining to this attribute:
'The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of this element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.'"
The integer represents the load order: the lower number the earlier it is loaded. Since this is the only app I'm doing this with, I set it to 0.
Thanks for the help - and thanks for JBoss!
You can also use a javax.servlet.ServletContextListener, defined in the Servlet 2.3 spec. The listener class has a callback method invoked when the web application is deployed, and another when the application is undeployed. It's a cleaner solution than loading servlets on startup, IMHO; unfortunately not available in Servlet 2.2.
you folks are nice tricky, but your approaches have some restrictions.
Recent weeks I meditated a lot about this subject because I'm realizing a J2EE project using JBoss/Tomcat.
The point is, that these services have (in my case) the properties:
1. They exist only once in the system
2. They access local files (containing settigs e.g.)
3. They create Threads which must work synchronized.
If you locate these services locally in the web tier (tomcat)
your application is not scalable because you violate (1.).
That means you only can run a unique Tomcat. Acceptable for small
applications, not acceptable for 'real world' applications.
On the other hand you can't locate them in a bean. (2.) and (3.)
violate EJB restrictions.
My solution was to use MBeans. They are really great and JBoss
has made the right approach to provide an appropriate media to
solve these proplems.
Unfortunately my clients urged me to provide an port to other
systems like JRun or Webspere. And is a problem because they are
poor concerning this issue.
I think it is nessesary to put this services in a new war which
contains these unique central services (including a management
console). It seems I must reinvent the JMX-wheel.
This is a common question for Java EE, and we have solved it in the same way described here.
But now comes a problem. This works as long as the EJBs are unsecured. Recently, we have looked at securing our EJBs to prevent unauthenticated access.
But if we do that, then how do we call those EJBs from the init() method of a servlet, when no authentication has been established?
Run-as role does not cut it - that just changes the role the servlet is running as, and does not actually enable us to have the servlet work authenticated.
So, my question is - if I have secured EJBs, how can I indicated that a servlet in a web app in the same EAR is trusted, and can call those EJBs?
Since you are invoking EJBs from the init method of the Servlet, can I presume that your EJBs here are only serving the application requirements, but not the end user/client requirements? If that's the case, can you not use different credentials to authenticate requests to those specific EJBs that are getting called from the init methods? For the normal methods used by the end user, you can make use of his/her credentials.
I want to be portable, thus reluctance to use MBean.
I tried also to do a client login in the init() method with hardcoded user id and password, and that did not work. I got no errors from the login but still got a authentication failure on EJB invocation due to a null principal.
Because we have encapsulated functionality in different EJBs, even if I created a new unsecured EJB, it would need to call the secured ones.
I strongly advise you to use 'Service Locator Pattern' by using Singleton Pattern. If you had done this methodolgy, you could have make the module more efficiency.