3

I have two Java projects: one is a library, and the other is a console application. In the library project, I have an abstract class with a few static member variables (for global access). It looks a bit like this:

public abstract class AbstractHelper
{
    public static final VarType someVar = new VarType();
}

I access the static member variables from the console application in two different classes.

For some reason, 'someVar' has unique instances across the two different classes that access it. If I access 'someVar' from an instance of Class A, I get a different object than when I access 'someVar' from an instance of Class B.

However, if I move AbstractHelper from the library project into my console application project, then it has the expected behavior (single instance of static member variable(s) shared across multiple classes)

Does anyone know why this happens?

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • 9
    Different class loaders. – Hot Licks Apr 15 '13 at 22:10
  • So, just to confirm.. referencing AbstractHelper from ClassA and from ClassB results in two different class loaders loading AbstractHelper? Why does it work when AbstractHelper is part of the same project? Is AbstractHelper not loaded in this case? – user1972838 Apr 15 '13 at 22:13
  • You can have two (or more) different instances of the AbstractHelper class, in different class loaders. This can happen several ways, most commonly if you have two different copies of the class in different jar files. If it does happen, there will, of course, be two different instances of the static variable. – Hot Licks Apr 15 '13 at 22:18
  • Note that you can circumvent this problem by referencing AbstractHelper early, from your "mainline code", before you delve into the two JARs. You can do this even if the class file itself is in the JARs. It's when your helper class is loaded "lazily" that you get this situation, because each project is running in it's own class loader environment. – Hot Licks Apr 15 '13 at 22:20
  • I thought I only had the "mainline" code (the console application) and one JAR (the library with AbstractHelper). Both ClassA and ClassB are part of the console application. – user1972838 Apr 15 '13 at 22:28
  • Somehow you're getting the class loaded in two different loaders. It may be that you're referencing the class AFTER the library does, and that's creating the second version. Just add a dummy reference to the class at the start of your program and see if that fixes it up. – Hot Licks Apr 15 '13 at 23:18
  • See http://stackoverflow.com/questions/4072041/scope-of-java-class-static-member – Raedwald Jun 25 '13 at 22:48
  • The simplest test would be to log/print/inspect `AbstractHelper.class.getClassLoader()` from both `ClassA` and `ClassB` and see if you get the same result. If you do, then it's not a class loading issue. – Costi Ciudatu Jan 06 '14 at 00:43

1 Answers1

0

This can happen by using different classloaders. OSGI, java-ee servers and several other technologies allow easy injection of different classloaders to the JVM.

You can resolve the problem: define both your library and your console application classes on the same classpath.

Kartal Tabak
  • 760
  • 1
  • 7
  • 18