Tomcat keep webapp api running - java

I'm trying to create a web application for tomcat 7, but my problem is that I want to keep the whole backbone of the application running, so that my servlets can call the functions. Ex. I have my com.example.Main class which house all the instances to things like User managers and such. But instead of getting the main instance redefined on each servlet call, It would get defined once for all the servlets to use.
Best Regards,
- Roe

As far as I understand, you want a singleton. Check this answer for implementation.
But note that singletons are "evil". A more webapp approach is to not have it as singleton, but initialize it once in a ContextLoaderListener and then put it as a ServletContext attribute. Then each servlet can obtain it by getting it from the servlet context.

I agree with Bozho - you seem to be talking about a Singleton and I share his reservations about using them.
If you do implement it as a singleton, or use Bozho's suggested solution, it is important for you to understand that there will be only one instance of the class, potentially being used by many servlets at the same time. As a result, it is your responsibility to make sure that the class is thread safe, or your application will produce unreliable results.

Related

Better way of distributing objects/classes inside a project

I have some Classes like Clipboard or ProcessRegister that I only want to run once in my Project, so only one instance.
My Question in now: How do I distribute those instances best in my Project.
ATM both are singleton and object they use the get an instance over the getInstance().
Another Idea of mine is to create a class Project, that has some static methods like getProjectClipboard()or getProcessRegister()that return the instances.
What is the best way to distribute them? Are there any patterns for that?
Greetings Dennis
There are mainly two patterns that can be used: the service locator, and dependency injection. The service locator pattern is probably the one you are referring to, where everywhere you look for a reference for these objects you explicitly retrieve it from a central location, which for simple java applications is usually a bunch of static methods. this is OK, and I don't think there is an overall better approach here, just make sure that you have only one static method for each singleton, and that you call it always.
Then a few years ago, a shift of mentality became mainstream, dependency injection, and its more popular framework... Spring, with this paradigm, in each place you need to access this singletons, you don't specify where they are, but your object get the correct references injected...
I would recommend you to look into dependency injection... and probably Spring, as it is the mainstream solution for it... I think that giving you more insgight into Spring is out of the scope of the question, but there is A LOT of documentation in Internet if you search for Spring tutorials or something similar...
Basically what you would do is create as spring beans each of your singletons, and then have spring injecting them into your objects... The caveat to this approach is that all of your objects have to be built by Spring, but in practice it doesn't suppose any disadvantage, it will actually make your life easier in terms of testings, maintenance...
Singletons, when done at language level, are global objects. This may work for small projects but is not the best idea when the project grows. There may evolve a situation where suddenly a singleton is only a singleton relative to a certain scope. Then you have to touch the object and every access to it.
That said if you have a Project object or an Application object these are good places to have accessors to Project-relative singletons. If Project is just a class that provides a lot of static accessors it is like a namespace. It is a win in clarity and will make refactoring easier but it doesn't change much in terms of architecture.
Best way to do singletons is not on language level but on application level. Very helpful are application and dependency frameworks like Spring (where the standard scope for beans is in fact singleton). If you later on see that the object isn't singleton you just change the configuration - but not the object itself.
As someone who is usually against the usage of stateful singletons (except for caching purposes), I would say: have one instance of these classes per running application and inject them where you need them (see Dependency Injection). That will also allow you to run the same application multiple times with different configuration in the same JVM.

Apache Tomcat: "Context variable"

I'm new to Tomcat and hence have a few question. I want to have certain objects available for my Context from any code. I was able to achieve this for a DataSource because that is the example used in the Tomcat guide.
I would like to add 2 additional objects:
Object A that uses this DataSource in the Constructor
Object B that uses Object A in it's constructor
How can I do this?
What's probably the easiest thing to do is use a ContextListener that inserts Objects A and B into the Context. See http://download.oracle.com/javaee/1.4/tutorial/doc/Servlets4.html for a usage example: in the contextInitialized method you can grab the datasource out of the context, create objects A and B and then store them back into the context.
According to the Tomcat 5.5 spec. found on http://tomcat.apache.org/tomcat-5.5-doc/config/globalresources.html I see that Context is not capable of doing such tricks and is not for such usages.
You'd like to have some objects available from "any code". If this any is confined to a single web application, than you can consider #Fermi's answer or maybe you should launch a Spring ApplicationContext. That might sound a bit too difficult if you're not familiar with Spring Framework yet, however if you keep developing your application I think there will be a certain point where things start to become easier if a Spring context already exists from the beginning. (Tell me in a comment if you need help with setting up Spring provided you choose that way.)

Accessing a servlet instance

while i can't really think of a practical use-case for such a scenario, but i purely intend this to be a curiosity driven question.
i understand the servlet container holds onto all the instances created of the servlets, and delegates request threads to these instances. it also makes sense to keep these instances managed, to avoid unwarranted calls to alter the lifecycle of servlet instances outside the purview of the container.
but is there really no way to access the servlet instances?
Prior to Servlet 2.1 (over a decade old already), you could use ServletContext#getServlet() for this. It's however deprecated since then. Simply because it's a bad design. If you want to invoke another servlet from inside a servlet in the request-response chain, just use RequestDispatcher#include(). If you want to invoke non-servlet specific methods of another servlet, then it's simply high time to refactor that code into a separate Java class which you could then import/use in the both servlets.
The container creates ONLY ONE instance of the Servlet and uses the same instance to serve multiple requests. There is "SingleThreadModel" which if you implement, container would create multiple instances of the Servlet but that is deprecated now.
Not through the standard Servlet API (so the answer is no).
You may, however, use your knowledge of the actual implementation and nasty tricks with reflection to get hold of the data structure used by the implementation to hold servlet instances, (so the answer is yes).
The servlet container may, however, have a SecurityManager in place prohibiting using said nasty tricks (so the answer is maybe).

Proper ApplicationContext usage?

I've recently started learning the Spring Framework, and I'm a bit unclear on how the ApplicationContext is supposed to be used - in both standalone and web applications. I understand that the ApplicationContext, once instantiated with the spring configuration xml, is the "spring container" and is a singleton.
But:
In the starting point - main method - of an app do I use ApplicationContext.getBean("className") and then rely on DI for all other registered beans or is there a way to use only DI?
Is there any other place besides the main method where I could/should use ApplicationContext.getBean("className")?
If and when should ApplicationContext.getBean("className") be used in a web app?
If in your opinion there is information I MUST know regarding DI related to web applications, even though I may not of specifically inquired about it, please share.
You need at least one call into the context from outside it, there's no avoiding that. With webapps, that part is hidden from you, and it it feels like everything is using DI, even though Spring's servlet glue code is doing some unpleasantness behind the scenes.
Could, yes; should, no. There are very few good reasons for calling getBean yourself.
The most obvious scenario is when you have a servlet filter that needs access to the context. FIlters aren't managed by Spring, and so cannot have stuff wired into them by Spring.
That's a bit too vague. Read the reference docs :)
I generally recommend only one usage of ApplicationContext.getBean() per application, and rely on the Spring configs to do the rest.
The exception applies in unit tests, where I want to load up a particular subset of beans (so I would explicitly load a bean that normally would be loaded from the top of my bean hierarchy).

Singleton in Java App Server.. How bad of an idea is this?

I am currently working on some older java code that was developed without App Servers in mind. It is basically a bunch of "black box code" with an input interface, and an output interface. Everything in the "black box" classes are static Data Structures that contain state, which are put through algorithms at timed intervals (every 10 seconds). The black box is started from a main method.
To keep this easy for myself, I am thinking of making the "black box" a Singleton. Basically, anyone who wants to access the logic inside of the black box will get the same instance. This will allow me to use Message Driven beans as input to the black box, and a JMS Publisher of some sort as the output of the black box.
How bad of an idea is this? Any tips?
One of the main concerns I have though, is there may be Threads in the "black box" code that I am unaware of.
Is there such thing as "application scoped objects" in EJB?
Note: I am using Glassfish
If you use a simple singelton, you will be facing problems once you enter a clustered environment.
In such scenario, you have multiple classloaders on multiple JVMs, and your sinlgeton pattern will break as you will have several instances of that class.
The only acceptable use for a singleton in an app server (potentially in a clustered environment) is when you the singleton is totally state-less, and is only used as a convenience to access global data/functions.
I suggest checking your application server vendor's solution for this issue. Most, if not all vendors, supply some solution for requirements of your sort.
Specifically for Glassfish, which you say you are using, check out Singleton EJB support for Glassfish. It might be as simple as adding a single annotation.
I would say that creating a singleton is actually the only viable idea. Assuming that code inside this "black box" is known to use static fields, it is absolutely unsafe to create two instances of this facade. Results are unpredictable otherwise.
Far from being a bad idea, it actually sounds to me like potentially quite a good idea.
Just from a program design point of view: if your black box is conceptually an "object" with properties and methods that work on them, then make it into an object, even if there'll only ever be one of them instantiated.
It should work, but there are some issues you may have to deal with.
Threading, as you have mentioned. An MDB is run in the EJB container where you cannot create your own threads, so you have a potential problem there. If you have access to the actual code (which it sounds like you do), you may want to do some refactoring to either eliminate the threads or use an "approved" threading method. The CommonJ TimerManager will probably work in your stated case since it is performing some task on an interval. There are implementations available for most app servers (WAS and Weblogic have it included).
Classloading - This is dependent on you configuration. If the singleton is created and manipulated from MDB's within the same EAR, you will be fine. Separate EAR's will mean different classloaders and multiple instance of you Singleton. Can't comment on whether this would be a problem in your case or not without more information.
I'm missing a point? You mentioned that the 'black box code' contains state. MDBs may be limited to 1 instance per destination but without proper configuration you will end up with a few MDBs. All of them working with your single instance of 'black box code'. For me it seems this is not a good idea, because one bean will override the 'black box code' state a other bean has created a few ticks before.
It seems to me that the artifact that better fits to your requirement is a JBoss MBean. (If you are thinking on JBoss as AS candidate).
Standard MBean Example
MBeans can also be deployed as Singletons, in case of JBoss clustering.
Clustering with JBoss
I hope that this is useful for you.
Rafa.
Fix the code to get rid of the statics as soon as possible. Singletons are not a step in the right direction - they just add extra misdirection.
Don't use Singletons where state may change.
Exposing the global instance of your black-box class doesn't seem like the way to go. Often times, singletons will seem like they will make things easier on you, and in a way they can, but it often comes back to bite you and you end up having to restructure a large chunk of your code.
In the webserver world, an object can be scoped to the request, the session, or the application. Perhaps what you need is a application-scope object.
Search the docs for "application scope object" or "application lifetime object".
Why not create a rest interface for the blank box thingy and let clients make http calls ?
IMO, it's a good idea to have an EJB container of your Singleton needs. In Java EE 6 placing a #Singleton annotation in your session bean gives you a named singleton.

Categories