GlassFish允许创建N个域。每个域都有自己的Java类(库等)和系统设置。
例如,我们有两个域 - domain1和domain2。
通过GF Web控制台(http://localhost:4848)为domain1设置了一个系统属性 - com.temp.foo=test1
。除了通过GF Web控制台(http://localhost:7575),还为domain2设置了一个系统属性 - com.temp.foo=test2
。
现在,在domain1
System.out.println(System.getProperty("org.temp.foo"))
//returns `test1`
在domain2中
System.out.println(System.getProperty("org.temp.foo"))
//returns `test2`
据我所知,GF及其所有域都在一个JVM实例中运行。我不明白在一个JVM独立系统属性的实例中它是如何可能的。谁能解释一下?
注意:我理解这可能是一个很长的解释,这就是为什么我只能按照我可以在互联网上阅读的顺序询问主要原则和解决方案/库名称。
答案 0 :(得分:4)
似乎理解“GF及其所有域都在JVM的一个实例中运行”是错误的。
根据GlassFish当前版本的documentation(第3章):
域包含一组受管理的GlassFish Server实例 一起。 [...] GlassFish Server实例是Java平台的单个虚拟机(Java 虚拟机或JVM机器)在GlassFish Server所在的单个节点上 运行
这意味着,任何域的每个实例都在自己的JVM中运行!因此,它们都可以拥有自己不同的系统属性。
公平地说:在GlassFish中有管理虚拟服务器的方法,它们似乎共享一个JVM,但我认为你不是在谈论它们。
答案 1 :(得分:2)
GlassFish,JBoss,WebSphere等产品......“只是”利用Java 类加载机制来创建隔离。通过使用多个类加载器,即使静态类字段也可以“不止一次”存在;并且每个“域”都有其非常特殊的版本。
Application Universe - 每个Java EE应用程序都有自己的类加载器Universe,它加载应用程序中所有模块中的类。
除此之外,请查看this。
换句话说:虽然System类显然代表了一个“系统视图” - 类加载机制应该可以为每个域提供不同的系统类实例。从而可以在每个特定于域的System类中具有特定于域的属性。但确切地说:我找不到明确的证据来支持这一说法。关于该主题,here和there应该有所帮助(后者表明甚至有办法篡改系统类加载器)。
但是进一步思考,这个想法存在一个问题:实际上有两个类加载机制。有“system / user”类加载器......和最初的bootstrap类加载器。
引导类加载器实际上是“烘焙”到JVM中(例如,它以本机代码实现) - 并且它不能被替换。
java.lang.System应该由该引导类加载器加载!
因此不可能使用“classloader magic”启用“每个域”系统属性!
我看到的另一个选项是创建一个拦截调用并操纵其结果的Java代理(请参阅here作为起点)。
但又一次;代理人“自我”引导完成后!
所以唯一合乎逻辑的结论(排除所有选项后留下的东西):问题的前提一定是错的!
不可能在相同 JVM上运行的不同“应用程序”提供不同的系统属性。幸运的是,Seelenvirtuose的伟大answer证实了这一结论。