0

I am looking for a way to maintain a truly global variable in Java, one that is valid for the entire JVM instance.

If I simply used a static field somewhere, it will fail if the class containing the field is loaded multiple times by different classloaders.

I can think of some nasty ways to resolve this, such as using only JDK standard classes (which should normally be loaded by the same classloader always), or asking a custom MBean to keep the global state, but these seem like hacks to me.

Disclaimer: I know that global state is bad, and yes, I avoid it whenever I can. Promise.

barfuin
  • 16,865
  • 10
  • 85
  • 132
  • 1
    If nothing else, then for my own burning curiosity, please explain the use case. – chrylis -cautiouslyoptimistic- Sep 26 '16 at 16:22
  • Use an `enum`. Note however that you want want is really rather "un OO". – Boris the Spider Sep 26 '16 at 16:22
  • @BoristheSpider The enum solution has the exact same issue as the static-field solution. – chrylis -cautiouslyoptimistic- Sep 26 '16 at 16:24
  • 2
    If your problem is related to multiple classloaders, then you need the global object to be loaded by the system classloader, or other shared classloader. How that is setup depends on how you run your app, e.g. in Tomcat, any jar file in the `CATALINA_BASE/lib` folder is added to the shared classloader. Once you class is loaded by the correct classloader, `static` fields will do what you want. – Andreas Sep 26 '16 at 16:27
  • 2
    Relevant http://stackoverflow.com/questions/7617990/how-to-share-objects-between-different-classloaders (and http://stackoverflow.com/questions/37912302/how-make-a-singleton-across-all-classloaders) – Tunaki Sep 26 '16 at 16:30

3 Answers3

2

System properties are available throughout one VM, but not cross-process. One VM, one set of properties.

Also see Scope of the Java System Properties

Community
  • 1
  • 1
Florian Heer
  • 694
  • 5
  • 17
1

The only reliable approach I can come up with that doesn't rely on manipulating the base classloader of the container would be to use JNI. Write an adapter to native code that uses a shared memory segment or other similar mechanism to back the global state.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
1

If your problem is related to multiple classloaders, then you need the global object to be loaded by the system classloader, or other shared classloader.

How that is setup depends on how you run your app, e.g. in Tomcat, any jar file in the CATALINA_BASE/lib folder is added to the shared classloader.

Once you class is loaded by the correct classloader, static fields will work the way you want them to.

Andreas
  • 154,647
  • 11
  • 152
  • 247