10

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.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • I got some comments for my answer; and I am not so sure any more if it is really correct. I updated it; but I don't mind if you decide to un-accept. I am even considering to put up a bounty on this question ... let me know if you are interested in that. – GhostCat Jun 26 '17 at 08:20
  • @GhostCat Thank you for informing. If you can, please, start a bounty - this question is still important and interesting for me. – Pavel_K Jun 26 '17 at 08:58
  • Bounty is out there! – GhostCat Jun 26 '17 at 09:18
  • Well ... My opinion: It first looked as if the class loading mechanism is the answer to this question. But now I second it. But that means that the system property must be the same for a single JVM. I see two possible causes of the behavior: 1) The idea of "GF and all its domains are running in one instance of JVM" might be wrong. Maybe they are two JVMs. _(I prefer this.)_ 2) Somewhere in the code the system property is overwritten prior to getting read in another place (unlikely, I think). – Seelenvirtuose Jun 26 '17 at 11:25
  • Too bad; I had hoped the bounty would result in some more upvotes around here ... hopefully you will at least make the "10" count ... – GhostCat Jul 03 '17 at 08:06

2 Answers2

5

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.

Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
  • So, here we go. I had hoped that the bounty would result in some more upvotes for all content here ... not just the question itself. But whatever ... – GhostCat Jul 03 '17 at 08:06
  • Could you say - one jvm is created for one domain (one jvm for domain1, one jvm for domain2) or one jvm is created for every virtual server (one jvm for domain1-virtserver1, one jvm for domain1-virtserver2, one jvm for domain2-virtserver1, one jvm for domain2-virtserver2 etc)? – Pavel_K Mar 06 '18 at 06:01
2

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.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Although you are right, OP is speaking about _system properties_. And these are usually VM wide. Your "answer" does not address this. – Seelenvirtuose Jun 21 '17 at 11:09
  • "The class loading mechanism still makes it possible to give different System class instances to each domain." => Do you have any proof for that? I mean ... it sounds right (and I do not know enough to second it), but some validation documents would be nice. (The anser might be correct, though ...) I ask, because looking at the source code for the `System` class shows that there are some very low level native startup behaviors. – Seelenvirtuose Jun 21 '17 at 11:14
  • @Seelenvirtuose As you suspected, the statement made by @GhostCat is false. Only the boot classloader is permitted to define classes in the `java.*` namespace, which includes `java.lang.System`. Therefore there can only be one `System` class loaded in the whole JVM. This is documented in the JavaDoc for the `ClassLoader#defineClass` method, which states that a SecurityException be thrown 'if an attempt is made to define a class in a package with a fully-qualified name that starts with "`java.`"'. – Neil Bartlett Jun 23 '17 at 21:06