Does every web application in web container will run in an isolated memory space? Is it a stand alone PROCESS?
Does every servlet run in an isolated memory space or a process?
What's the diff between java process and os process, Does every java process will run in an OS process?
Application data are isolated from the other applications in same web container like Tomcat or application server like jboss or Webloogic. But you should be aware that java Servlets are Classes that serve web based requests and nothing more!
as you know Classes are templates for creation objects or in technical speech for instantiation of objects, so usually web containers at the start up state or application deployement state create some objects from Servlet classes ready to use for serving requests (Servlet pool)
the next thing that would be fine to mention here is that if you declare a variable in Class scope you are using this variable in none thread-safe manner, it means that it is shared by other instances.
if you do some practice on this kind of variables(class scoped variables) you can see results and odd value changes!
Related
Please consider me as a novice and this is my first web app I am creating.
I am planning to develop a web application where the traffic I am expecting is around 50 users will access the application at a single time.
The webapp is developed with Vaadin (for UI) and respective business logic implemented with Java. DB used would be MySQL. The war will be deployed in Tomcat.
So, my question is do I need to modify anything in Tomcat properties or anywhere to make the web app as multi user application (i.e. each users need to access and use application as though they are only one using the application)?
I tried to access a prototype developed using Vaadin in both Chrome and Firefox and could see both sessions running without an impact on another.
But please let me know suggestions.
You must keep in mind that even if tomcat and vaadin manage multiple sessions, your server application will have only 1 instance. So if you use singletons, static methods or fields, use them with care: they should never hold session-dependant content. Try to favour stateless methods over statefull.
Apart from that, there shouldn't be any problem.
It should not have any code changes if you handle the session and your business logic with statefulness properly.
There might be some configuration changes, like increasing the database connection pool size, it depends on what kind of connection pooling you are using and what is the default size etc.
Apart from that it should work just fine.
Vaadin is built on top of Jakarta Servlet technology (formerly known as Java Servlet). See Wikipedia. Indeed, Vaadin is a servlet, a much bigger and more sophisticated servlet than most.
Within a Java Servlet container (engine) such as Apache Tomcat or Eclipse Jetty, any particular servlet has only a single instance running. If three requests from three users arrive at the same time, there are three threads running through that same single instance for that particular servlet. So a servlets are inherently a highly threaded environment.
If you share any variables or resources between those threads, you must be very careful. That means mandatory reading, rereading, and fierce study of the book Java Concurrency in Practice by Brian Goetz, et al.
While the Web and HTTP were designed to be stateless delivery of single documents, that original vision has been warped by the desire to make web apps. To maintain state, a servlet automatically maintains a session. Vaadin represents this session state in its VaadinSession object. All data in all the forms, along with business logic, running for each user is maintained as part of that session.
Depending on your particular Vaadin app, and when multiplied by the number of concurrent users, this may add to a large amount of memory. You should monitor your server to make sure you have enough available RAM on your server.
do I need to modify anything in Tomcat properties or anywhere to make the web app as multi user application (i.e. each users need to access and use application as though they are only one using the application)?
No, nothing for you to set or enable. Tracking the requests/responses and session for each user is the very purpose of a servlet container. From the moment it launches, every servlet container expects multiple users. As a Servlet, Vaadin is built to expect multiple users as well. The only trick is making your own code thread-safe, hence the book suggestion.
I tried to access a prototype developed using Vaadin in both Chrome and Firefox and could see both sessions running without an impact on another.
Concurrency problems can be very tricky to detect and debug. Often potential problems occur on the random chance of coincidental timing. You need to focus on properly designing your code in the first place, rather than relying on testing. Again, hence the book recommendation.
Of special note, since you mentioned using a database, is JDBC drivers. Deploying them in a Servlet environment can be tricky. Basically you need to not bundle them within your Vaadin web app WAR file. Instead, deploy the JDBC driver separately within a shared library folder within Tomcat. If using Maven to drive your project, direct Maven in the POM file to give the dependency for your JDBC driver a scope of provided. This has nothing to do with Vaadin specifically, it applies to all servlets. Search Stack Overflow as this issue has been extensively addressed.
I'm a researcher in programming languages and I'm using dynamically created/loaded classes
to implement multi-stage metaprogramming.
I'm thinking about using a tomcat server to expose my works, so I will write a Servlet that create
java classes and loads them (tons of them).
To properly garbage collect such created classes the corresponding class loader must be garbage collected.
Is this my responsibility as a Servlet writer or the responsibility of the tomcat framework?
If is not a responsability of tomcat framework, is this an open security issue?
Thanks!
Tomcat unreferences the web application classloader and the objects it created from it (servlets, filters, listener, …) upon undeployment of the application. This should make the web application classloader, all its classes and objects eligible for garbage collection (unless you have a classloader leak).
There are two possibilities that come to my mind that you could count as a security issue. First if you have a classloader leak one web application might access classes from another web application that runs inside the same Tomcat instance. Second if you allow users to create classes through your web application that's obviously going to be an issue.
It's up to you to free the ClassLoaders. Tomcat is a servlet engine, it won't meddle with your classloading or unloading. Still unclear on how it would be a security issue though.
I have my own framework for building java web app, and within that framework, I create my own Threadpool executor service which is singleton. So, each web app that using my framework will create 1 Threadpool executor on startup, to be use internally.
My questions are:
Let say I deploy 2 web apps in the same Tomcat, would those 2 Threadpools interfere each other?
Is there any possibility where a thread from the 1st web app would accessing the Threadpool from the 2nd web app, or vice versa?
Do I need to create a single Threadpool service for all my web apps that resides in a single servlet container, instead of one for each web app?
Thank you.
No. The webapps should be isolated by ClassLoader within Tomcat, so each should have their own instance of the singleton.
So long as the answer to #1 is in fact no, then the answer to this is also no.
Probably not.
As an aside, my understanding is that, as a general rule Java EE web apps are not supposed to spin up new threads.
I got 4 stand alone java programs inside a jar... Its a jar of spring 3.0.5 + Maven project...Here is my requirement
1) The first java program will load the spring application context.
How to make that application context available to the other stand alone java programs when they are invoked? Each of them runs in their own JVM and I am thinking there is a need for me to save the application context in some sort of cache? and each of those programs will retrieve the application context when they need it and update the context back into the cache
I cannot load the application context in each of those programs...
Please help me here on whether my thought process is correct or is there any other solution?
You cannot (or at least it isn't a good idea) to attempt to share a Spring application context across multiple applications. That is why it as called an "application context" it defines the objects that interact in a single application.
I would restructure your application context into 4 smaller application contexts for the 4 different applications, if they are indeed different applications.
Another alternative, is to adjust your design so that the first application exposes an interface (RMI or REST or some other RPC mechanism) so that the other 3 applications can interact with the first. This should be the last resort, as it is much more complex.
I have multiple clients:
client 1 - 40 users
client 2 - 50 users
client 3 - 60 users
And I have a web application that is supposed to serve all the clients.
The application is deployed into Tomcat. Each client has it's own database.
What I want to implement is the single web application instance which servers all the clients. The client (and the database to connect to) is identified by the context path from the URL.
I.e. I imply the following scenario:
Some user requests the http://mydomain.com/client1/
Tomcat invokes a single instance of my application (no matter which context is requested)
My application processes the rest of the request thinking that it's deployed to /client1 context path, i.e. all redirect or relative URLs should be resolved against http://mydomain.com/client1/
When the client 2 requests the http://mydomain.com/client2/, I want my application (the same instance) now process it just like if it was deployed to /client2 context path.
Is this possible with Tomcat?
Your application has to do this not tomcat. Now you could deploy your application in three new contexts (client1, client2, client3) with slightly different configuration for the database, and if you are careful to use relative URLs (ie don't do things like /images) then you can do this without changes. This is the transparent way of making your application reusable in that your application is unaware of the global picture that you have 3 different instances of itself running. That means you can easily deploy more or more without having to change your application. You just configure a new instance and go. This only requires you don't use absolute URLs to resources. Using ServletContext.getContextPath() and using .. in your CSS, scripts, etc is helpful as well here.
Probably one of the biggest advantages working this way is that your app doesn't care about global concerns. Because its not involved in those decisions you can run 3 instances on one tomcat server, or if one client needs more scaling they can be moved to their own tomcat server easily. By making your app portable it has forced you to deal with how to install your app in any environment. This is a pillar of horizontal scaling which your situation could very much take advantage being you can split your DB data without having to rejoin them (huge advantage). The option you asked about doesn't force you to deal with this so when the time comes to deal with it it will be painful.
The other option is more involved and requires significant changes to your application to handle this. This is by parsing the incoming URL and pulling out the name of the client then using that name to look up in a configuration file for the database that should be used for that client. SpringMVC can handle things like extracting variables from URL paths. Then making sure you render everything back to them so it points to their portion of the URL. This probably would require a lot of the same requirements as the first. You can use absolute URLs for things like javascript, CSS, and images, but URLs to your app would have to be rewritten at runtime so that it is relative to the requesting client. The benefit is that your only load your application once.
Just as an aside, if you host your CSS, Javascript, images on a CDN in production then both of these options must be relative URL aware. Upsides and downsides to using CDNs as well.
While that sounds good it might not be a good thing because all clients use the same version of the app. Also if you bring down a the app to fix client1 to do maintenance it affects all clients. If you think you'll have to do customization per client then this option will get messy quick. Upgrading a single client means all clients must upgrade and depending on your business model this might not be compatible. Furthermore, I'm not entirely sure you'll save a lot of memory either running only a single version of the application because most apps only take up 10MB of code loaded. A vast majority of the memory is in the VM and processing requests, and using a single Tomcat instance means you share the VM. And with 1 or 3 instances running you still have the same number of requests. You might see a difference of 30-100MBs which in todays world is chump change, and all of those other concerns aren't addresses if you choose to save only a couple of MB.
Essentially there are facilities in Tomcat to aid you in doing this (multiple contexts), but its mostly up to your application to handle this especially if its a single instance.