GlassFish allows creating N domains. Every domain has its own Java classes (libraries etc) and system settings.
For example, we have two domains - domain1 and domain2.
Via GF web console (http://localhost:4848) one system property was set for domain1 - com.temp.foo=test1. Besides via GF web console (http://localhost:7575) one system property was set for domain2 - com.temp.foo=test2.
Now, in domain1
System.out.println(System.getProperty("org.temp.foo"))
//returns `test1`
And in domain2
System.out.println(System.getProperty("org.temp.foo"))
//returns `test2`
As I understand GF and all its domains are running in one instance of JVM. And I don't understand how it is possible in one instance of JVM separate system properties. Could anyone explain?
Note: I understand that it can be a very long explanation that's why I am asking only about main principle and solutions/libraries names in an order I could read about them on the internet.
It seems that the understanding "GF and all its domains are running in one instance of JVM" is wrong.
As per GlassFish current version's documentation (chapter 3):
A domain contains a group of GlassFish Server instances that are administered
together. [...] A GlassFish Server instance is a single Virtual Machine for the Java platform (Java
Virtual Machine or JVM machine) on a single node in which GlassFish Server is
running.
That means, every single instance of any domain is running in its own JVM! As a consequence, they all could have their own different system properties.
To be fair: There are means for administering virtual servers in GlassFish, that seem to share a JVM, but I think you are not speaking about them.
Products such as GlassFish, JBoss, WebSphere, ... "simply" make use of the Java class loading mechanism to create isolation. By using multiple class loaders, even a static class fields could exist "more than once"; and each "domain" gets its very special version of that.
Start reading here, or there for example:
Application Universe – Each Java EE application has its own class loader universe, which loads the classes in all the modules in the application.
And beyond that, look into this.
In other words: although the System class obviously represents a "system view" - the class loading mechanism should make it possible to give different System class instances to each domain. Thereby making it possible to have domain-specific properties within each domain-specific System class. But to be precise: I could not find clear evidence to back up this statement. On that topic, here and there should help (the later one indicating that there even ways to tamper with the system classloader).
But thinking further, there is a problem with that idea: there are actually two class loading mechanisms. There "system/user" class loaders ... and the initial bootstrap classloader.
And the bootstrap classloader is actually "baked" into the JVM (it is implemented in native code for example) - and it can't be replaced.
And java.lang.System should be loaded by that bootstrap classloader!
So it is impossible to use "classloader magic" to enable "per domain" System properties!
The other option I see is to create a Java agent that intercepts calls and manipulates their result (see here as starting point).
But again; agents come "after" bootstrapping has completed!
So the only logical conclusion (taking what is left after excluding all options): the premise of the question must be wrong!
It is simply impossible that different "applications" running on the same JVM give different system properties. And luckily, the great answer by Seelenvirtuose confirms that conclusion.
Related
I want to select different implementations of classes dynamically, based on a runtime condition. Let's say I have a class with fully qualified class name C. My running system may have many definitions of class C, each of which is in its own jar. I have a runtime condition (held in a ThreadLocal) that tells which definition should be chosen.
I was asked in a comment to clarify the original requirement, so I will clarify the requirement as best I can. There are multiple teams writing software to contribute to this system - something like 4000 classes in many independent modules. What's more they can change over time. They are currently running in separate JVMs so there is no issue with classes overlapping. Now we are considering running them in the same JVM with multiple releases running simultaneously on the same JVM; which specific set of implementations used being differentiated by the ThreadLocal. So the original problem was how to allow a thread to at one time run one set of implementations and at another time run another.
I have a tomcat application that is currently using OpenJDK 8.
I believe I can write a custom ClassLoader that manipulates the classpath to choose the definition of C differently based on the ThreadLocal. But I'm afraid the results will be cached somewhere such as JVM Code Cache. Unless I can override that behavior too, the next time the class is needed, the runtime condition may have changed and the version in the cache would be wrong.
Is there any way to do what I need to do?
Well, the simple solution would be to NOT have multiple definitions of class C, but instead have 'class C1', 'class C2', etc (i.e. they don't overlap and can be simultaneously loaded) and then your runtime property just picks the right one as appropriate. That is way-way the easiest solution, so strongly consider it first. But it may not meet your needs.
If you truly need to have multiple separate implementations of a single 'class C', then what you are effectively talking about is a 'hot swap' scenario. Fortunately, Tomcat and other tools got good (with limitations) at hotswapping long-time-back. You likely already know this, but 'hot swapping' meets the need of a developer who codes 'class C', deploys it to a container, tries it out, realizes it has a glitch, makes a quick code edit and wants to run the modified code without relaunching the container. Hotswapping does this by basically overlaying the new implementation in the JVM. It only works up to a point because each 'redeploy' pollutes the 'class space' of the JVM and you eventually run of of 'class space memory' and/or the JVM starts going unstable. Depending on your needs and tolerances though, hotswapping might work.
The clean way to do what you want is to define C as an interface, then you can load and use any class that implements interface C
By definition, there can be a single instance of a Java singleton class. Except of course when there's obviously several, including the same code running on different physical machines, virtual machines, Java Virtual Machines.
Is the insurance that a JVM has a single instance of a singleton class?
In what domain is a Java singleton class unique? What relation to the notion of application, whatever the meaning of that is? What relation to the notion of process or thread in the operating system hosting the JVM? Of user connection in a web server? Does it change if we are talking Apache or Tomcat?
I design a Java class to be supplied to other software developers, which will access a remote functionality through it. That functionality is implemented redundantly on several distant machines. The class keeps a list of these machines, tracks their response time, and makes sure the requests received from its callers are sent to the currently most responsive distant machine. That's a good use case for a singleton.
I have only a vague idea of what the other developers will call my class from. I know that's going to be a web server, accessed by end users. I know the other software developer's code is written in Java (because the code I replace is C and called from JNI). They talk about calling my code from several apps they make on the same machine, but I do not know what exactly that means. Definitely some run their web server on Tomcat with multiple apps in the same server. Another apparently lean towards Apache Web Server, and yet another mentioned NGINX. The less I know about what they do, the better.
I know my code will run in relatively few JVMs instances on the same machine (as shown by top), and I can live happy with that few instances of my singleton. It would be a serious issue if there was 1 singleton per end user of the web server, a mild issue is there was one per "app". I'd like to know at the design phase, rather than discover in the field.
Usually the class loader loads only a single instance of each class into memory. So all static variables exist only once per Java VM.
But in web applications (e.g. on Apache Tomcat or similar) it's a bit different because each application has its own class loader and there is another class loader for shared libraries.
When your Tomcat runs two applications which contain the same library (inside the *.war), you have effectively two instances of the same library in memory, so their static variables exist twice. But when two applications share a library from the lib folder, then you have only one instance in memory.
However, by implementing a custom class loader, you can alter that behavior and then it's up to you.
Thread do not affect this normally unless you write your own class loader with specific features for threads.
I know that a servlet container, such as Apache Tomcat, runs in a single instance of the JVM, which means all of its servlets will run in the same process.
I also know that the architecture of the servlet container means each web application exists in its own context, which suggests it is isolated from other web applications.
As depicted here:
Accepting that each web application is isolated, I would expect that you could create 2 copies of an identical web application, change the names and context paths of each (as well as any other relevant configuration), and run them in parallel without one affecting the other. The answers to this question appear to support this view.
However, a colleague disagrees based on their experience of attempting just that.
They took a web application and tried to run 2 separate instances (with different names etc) in the same servlet container and experienced issues with the 2 instances conflicting (I'm unable to elaborate more as I wasn't involved in that work).
Based on this, they argue that since the web applications run in the same process space, they can't be isolated and things such as class attributes would end up being inadvertently shared. This answer appears to suggest the same thing
The two views don't seem to be compatible, so I ask you:
Do servlet containers prevent web applications deployed to the same container from conflicting with each other?
If yes, How do they do this?
If no, Why does interference occur?
and finally, Under what circumstances could separate web applications conflict and cause each other interference?, perhaps scenarios involving resources on the file system, native code, or database connections?
The short answer is that the servlet container isolates the applications by using a separate classloader for each application - classes loaded by separate classloaders (even when from the same physical class files) are distinct from each other. However, classloaders share a common parent classloader and the container may provide a number of other container-wide resources, so the applications are not completely isolated from each other.
For example, if two applications share some common code by each including the same jar in their war, then each application will load their own instance of the classes from the jar and a static variable (e.g. a singleton) of a class in one application will be distinct from the static variable of the same class in the other application.
Now, take for example, that the applications try to use java.util.Logger (and presumably don't include their own instance of the Logger classes in their war files). Each application's own classloader will not find the class in the war file, so they will defer to their parent classloader, which is probably the shared, container-wide classloader. The parent classloader will load the Logger class and both applications will then be sharing the same Logger class.
Servlets in the same container will share some resources. I think it should be possible to deploy the same web application twice in the same container provided that you give each a different name and they don't collide on a particular resource. This would theoretically be the same as deploying two different servlets which just happen to have the same implementation, which we do all the time.
Some shared resources, off the top of my head (and I'm not an expert so don't quote any of this!):
Libraries (jars) in tomcat/common/lib (Tomcat 5) or tomcat/lib (Tomcat 6).
Settings in the global server.xml, web.xml, tomcat-users.xml
OS provided things, such as stdin/stdout/stderr, network sockets, devices, files, etc.
The logging system.
Java system properties (System.getProperty(), System.setProperty())
I suspect... static variables? I'm not sure if the ClassLoader design would prevent this or not.
Memory. This is the most common problem: one servlet can deny others availability by consuming all memory.
CPU - especially with multi-threaded apps. On the HotSpot JVM, each Java thread is actually an OS-level thread, which are expensive and you don't want more than a few thousand of them.
Doubtless there are more.
Many of these things are protected by a security manager, if you're using one.
I believe the isolation is in the class loader. Even if two applications use the same class name and package, their class loader will load the one deployed with the application.
I want to run multiple versions (like myapp2.1, myapp2.2 ...) of several Java Servlet based web applications parallel.
One possibility could be to deploy each version to a separate servlet context (which should have its own class loader?!). But I think it will be hard to manage and won't be flexible, since an application is a quite large block. What if an application should contain a service in two different versions? Maybe that is not a good idea ...
The environment will be GlassFish >= 3.0.
What is a better way to run multiple versions of a servlet application parallel? Could OSGI help?
Each web application will be loaded using its own ClassLoader (at least any container I know of; I can't imagine why a container would not do this). So, it should just work. Different versions of your classes will not interfere with one another.
Make sure you do not include any of your classes in the container's own ClassLoader -- for example by putting a .jar in lib/ in Tomcat's directory (not sure of the equivalent for Glassfish). That would be shared by all web applications, and would override whatever is in the web app.
One possibility could be to deploy each version to a separate servlet context (which should have its own class loader?!).
J2EE applications use separate hierarchy of ClassLoaders and are isolated from each others. Quoting Classloaders and J2EE:
J2EE classloader hierarchy
J2EE specifies that a hierarchy of
classloaders is needed to achieve the
isolation between applications, but
leaves it to the vendors to define the
exact structure. However to comply
with the J2EE specification, most
vendors have classloaders for each of
the J2EE application components
depending on its location. Further,
these classloaders have a hierarchy
among themselves, i.e. they have a
parent-child relationship. Figure 21.5
shows a sample hierarchy of
classloaders. Note that each
application server’s classloader
hierarchy might slightly differ.
Application server vendors sometimes
tend to treat two or more of these
classloaders as one. For instance, a
certain application server might treat
Application classloader and EJB
classloader to be the same. But the
general concepts behind the hierarchy
remain the same.
Sample Classloader Hierarchy in J2EE Application Servers http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE_files/image016.jpg
Figure 21.5 Sample Classloader Hierarchy in J2EE Application Servers.
So, yes, each webapp would have its own ClassLoader (thanks god).
But I think it will be hard to manage and won't be flexible.
Why hard to manage? Why not flexible? How many instances are you going to run in parallel? Actually, what problem are you trying to solve? You may get better answer if you describe the real problem. So, can you elaborate a bit?
Unless you explicitly configure it to be so, all servlets are multi-threaded and can be invoked several times at once.
So, do you want several web applications with the same code but different names or several servlets inside the same web applciation with different configurations? Please edit your question with a scenario.
EDIT: You have now edited the question.
You can simply just name the war file you deploy like application20091230, application20091231, application20100101 and let Glassfish assign it to the corresponding URL. If date is not granular enough, then either a datetime or a buildnumber.
That's what we do for having several versions in a single internal test server.
I have a web application and two class files,
First class is MyClass.class which is inside the abc.jar file (WEB-INF/lib/abc.jar) and
Second class is YourClass.class which is inside classes folder (WEB-INF/classes/ YourClass.class).
My question is which class would load first when the Application starts? And Why ?
In my experience you can't predict the order in which the classes are loaded by the JVM.
Once I made a test runner (kinda Maven's Surefire) and with the same JVM and OS it loaded classes in different order when run in different machines. The lesson learnt:
You shouldn't build your applications
to depend on class loading order
Classes are loaded as needed, for some definition of "needed". Exactly when a class is loaded is dependent upon the JRE implementation, javac implementation, exactly what thread are up to, server code and, of course, application code. It's a bad idea to make assumptions in this area. If you want to see what happens for a particular run, you can use -verbose:class
Sun's class loader docs always say WEB-INF/classes OR WEB-INF/lib, but doesn't say which one will be checked first.
From IBM docs:
"The rules for loading classes are spelled out in detail in the JVM specification. The basic principle is that classes are only loaded when needed (or at least appear to be loaded this way -- the JVM has some flexibility in the actual loading, but must maintain a fixed sequence of class initialization). Each class that gets loaded may have other classes that it depends on, so the loading process is recursive."
So I think the answer is: It depends on which classes is needed in your application first.
As duffymo points out, this can vary. One way you might ascertain the sequence for this specific app is to insert Response.Write text in the class constructors and web web app page loading methods. "Instantiated object in Class A", "Opened web page MyPage", and so on.
Once you've figured out the sequence, comment out the code for those so you can reuse them later to verify that you haven't made a change (such as instantiating an object earlier or later) that affected the sequence.