Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2008

Tip: Looking for answers? Try searching our database.

Static Variables and JAR Files

Thread view: 
Jason Cavett - 03 Mar 2008 19:23 GMT
I am curious - does the scope of static variables carry across
different JAR files?

Here's the issue:

BaseClass is in "BaseClasses.jar"
ExtendedClassA extends BaseClass is in "AnotherPackage.jar"
ExtendedClassB extends BaseClass is in "EvenAnotherPackage.jar"

BaseClass has a static object (ObjectX).  Now, normally, this static
object is static across all of the subclasses.  However...

These JAR files (AnotherPackage and EvenAnotherPackage) are being read
in by a separate tool.  When ExtendedClassA and ExtendedClassB are
used within the context of this tool, ObjectX is instantiated twice
and has two separate values.  As far as I can tell, the tool runs
ExtendedClassA and ExtendedClassB within the same JVM, so I am unsure
of what is going on.

Does anybody have any insight into what is going on here?  (Sorry for
being vague.  I'm not actually working the project, but I'm curious
from an academic standpoint.  Another group ran across this problem
today.)
Knute Johnson - 03 Mar 2008 19:37 GMT
> I am curious - does the scope of static variables carry across
> different JAR files?
[quoted text clipped - 19 lines]
> from an academic standpoint.  Another group ran across this problem
> today.)

I'm curious how you instantiate a static object?  What tool are they using?

Signature

Knute Johnson
email s/nospam/knute/

Lew - 03 Mar 2008 20:13 GMT
>> I am curious - does the scope of static variables carry across
>> different JAR files?
[quoted text clipped - 21 lines]
>
> I'm curious how you instantiate a static object?  What tool are they using?

The scope of a static class variable is the entire execution of the JVM once
the class is loaded.  Its accessibility is that declared for it.

When you say "ObjectX is instantiated twice and has two separate values",
first of all, instance names are supposed to begin with a lower-case letter.
Anyway, do you mean there are two simultaneous instances of
'BaseClass.ObjectX' (we really have to improve these names!)?  Or do you mean
there is one variable 'BaseClass.ObjectX' that points to different objects at
different times?

If it's the first case, two simultaneous instances of the "same" static
variable, it's because the class was loaded two different times by two
different ClassLoader instances.  That causes the "same" class to actually be
two different classes, one belonging to each ClassLoader.

If it's the second case, the same variable but it points to different objects
at different times, it's because something changed what the variable points to
after it was set the first time.

Signature

Lew

Owen Jacobson - 04 Mar 2008 13:55 GMT
> >> I am curious - does the scope of static variables carry across
> >> different JAR files?
[quoted text clipped - 24 lines]
> The scope of a static class variable is the entire execution of the JVM once
> the class is loaded.  Its accessibility is that declared for it.

This isn't necessarily true.  A single class Foo can be loaded in
multiple class loaders so long as the common parents do not also load
Foo.  This means that static members of Foo may exist more than once:
each time the Foo class is loaded within a classloader, another
occurrence of Foo's static members comes into being .  Foo's static
initializer is also run each time the class is loaded.

Consider the following class Foo:

package dyn;

public class Foo {
   static {
       System.out.println("Class " + Foo.class + " loaded on CL="
               + Foo.class.getClassLoader());
   }
}

This class is not available on the bootstrap classpath: it's in a
separate directory called Dynamic relative to the working directory.
The main class

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class DCL {
   public static void main(String[] args) throws
MalformedURLException,
           ClassNotFoundException, InstantiationException,
IllegalAccessException {
       URLClassLoader cl1 =
               new URLClassLoader(
                       new URL[] { new URL(
                               "file:Dynamic/") });
       cl1.loadClass("dyn.Foo").newInstance();

       URLClassLoader cl2 =
               new URLClassLoader(
                       new URL[] { new URL(
                               "file:Dynamic/") });
       cl2.loadClass("dyn.Foo").newInstance();
   }
}

generates the output

Class class dyn.Foo loaded on CL=java.net.URLClassLoader@2e7263
Class class dyn.Foo loaded on CL=java.net.URLClassLoader@5eb0a9

Since Cavett hasn't told us what this "separate tool" is, it's
entirely possible that it's engaging in some dynamic classloading and
actually is running the static initializer for ObjectX twice (and
initializing static final members twice).

-o
Mark Space - 03 Mar 2008 20:23 GMT
> These JAR files (AnotherPackage and EvenAnotherPackage) are being read
> in by a separate tool.  When ExtendedClassA and ExtendedClassB are
> used within the context of this tool, ObjectX is instantiated twice
> and has two separate values.  As far as I can tell, the tool runs
> ExtendedClassA and ExtendedClassB within the same JVM, so I am unsure
> of what is going on.

Obviously, when you make a new class via inheritance, it gets it's own
copy of the static variable.  So there will be one static for the parent
class, and one for the child class.  The static is a "class variable"
and since there are two classes (parent and child) there are two static
variables.

There could be other things going on.  The tool may be using
ClassLoaders to load the jar files.  When a separate ClassLoader is
used, classes loaded under separate ClassLoaders are separate classes.
Even if there was no inheritance involved, there may still be two
separate ObjectX and two copies of the static variable.  If this is the
case, there will also be two copies of the class object itself (it gets
loaded twice, to separate memory areas) which is the root cause of this
particular static issue.

You may need to look at the documentation of the tool you are using, and
decide how you need to correctly deal with this situation.  Just
curious: what tool are we talking about here?  Like maybe a web container?

There could be other issues too.  Fire up the debugger, read the source
code, decompile some tool code, or bug the manufacturer support site.
Stuff happens.
Eric Sosman - 03 Mar 2008 21:05 GMT
>> These JAR files (AnotherPackage and EvenAnotherPackage) are being read
>> in by a separate tool.  When ExtendedClassA and ExtendedClassB are
[quoted text clipped - 8 lines]
> and since there are two classes (parent and child) there are two static
> variables.

    Please predict the output of this simple demonstration, and
then test your prediction:

    class Foo {
       static int count;

       public static void main(String[] unused) {
           Foo.count = 1;
           Bar.count = 2;
           System.out.println("Foo.count = " + Foo.count);
           System.out.println("Bar.count = " + Bar.count);
       }
    }

    class Bar extends Foo {
       // Mark says a copy of `count' is inherited here
    }

    If Foo.count and Bar.count are two distinct variables, the
output will show two different values.  If it shows the same
value for both, they cannot be distinct.  Place your bets!

Signature

Eric.Sosman@sun.com

Mark Space - 03 Mar 2008 21:37 GMT
>> Obviously, when you make a new class via inheritance, it gets it's own
>> copy of the static variable.  So there will be one static for the
[quoted text clipped - 4 lines]
>     Please predict the output of this simple demonstration, and
> then test your prediction:

Well clearly I was mistaken.  That's pretty frustrating too because I
looked this up before I posted, and the documentation and examples
seemed to indicate that there would be a copy of a static variable.

Even the JLS doesn't really say, it just says that non-private fields
are inherited.  I'm not sure how one is supposed to determine when
documentation, including the JLS, should be taken at face value and when
one has to experiment carefully to determine what the docs actually meant.

I'm not sure what else to add, other than I'm really fuming over having
missed that.
Eric Sosman - 03 Mar 2008 21:58 GMT
>>> Obviously, when you make a new class via inheritance, it gets it's
>>> own copy of the static variable.  So there will be one static for the
[quoted text clipped - 16 lines]
> I'm not sure what else to add, other than I'm really fuming over having
> missed that.

    Standardese can sometimes be as opaque as a meter of mud.
Perhaps the thing to remember here is that "inherit" does not
mean "make a copy of."  The subclass "inherits" the accessible
members of its superclasses, but that doesn't mean it makes
its own local copies of them.  They continue to "reside in" or
"belong to" the superclasses, although they can be accessed
through the subclass.

Signature

Eric.Sosman@sun.com

Lew - 04 Mar 2008 00:38 GMT
Mark Space wrote:
>> Even the JLS doesn't really say, it just says that non-private fields
>> are inherited.  I'm not sure how one is supposed to determine when
[quoted text clipped - 4 lines]
>> I'm not sure what else to add, other than I'm really fuming over
>> having missed that.

>     Standardese can sometimes be as opaque as a meter of mud.
> Perhaps the thing to remember here is that "inherit" does not
[quoted text clipped - 3 lines]
> "belong to" the superclasses, although they can be accessed
> through the subclass.

The JLS actually clarifies this in an example of when a static field is hidden
and when it isn't:
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.3.1>
> the simple name x now refers to the field Point.x.
> Code in class Test may still refer to that same field as super.x.
> Therefore, the output from this variant program is:
>
>     2 2

But generally I'm having the same trouble finding as clear a statement of this
principle as I remember reading somewhere.

Signature

Lew

Eric Sosman - 04 Mar 2008 02:01 GMT
> [...]
> But generally I'm having the same trouble finding as clear a statement
> of this principle as I remember reading somewhere.

    Maybe my "meter of mud" was an understatement ...

Signature

Eric Sosman
esosman@ieee-dot-org.invalid

Thomas.a.mcglynn@nasa.gov - 03 Mar 2008 21:13 GMT
> > These JAR files (AnotherPackage and EvenAnotherPackage) are being read
> > in by a separate tool.  When ExtendedClassA and ExtendedClassB are
[quoted text clipped - 8 lines]
> and since there are two classes (parent and child) there are two static
> variables.

To clarify this since I think it could be misinterpreted:
If you try the following program:

  class A {
     static String var = "ClassA";
  }
  class B extends A {
  }

  public class Test {
      public static void main(String[] args) {
          B.var = "SetInProgram";
          System.out.println("A.var is:"+A.var);
      System.out.println("B.var is:"+B.var);
      }
  }

The output of this program

  A.var is:SetInProgram
  B.var is:SetInProgram

shows that there is only one field even though B extends A.  I can add
a declaration to B:

  class B extends A {
     static String var = "ClassB";
  }

Now when I run this I get:

  A.var is:ClassA
  B.var is:SetInProgram

The definition in B hides the one in A (or 'shadows' I'm never quite
sure of which terminology is used where) -- though a user could still
reference it as A.var.

So regardless of the number of times we extend a class, we declare
only a single instance of its static fields.  However if the new class
does not hide the original field, we can use a new name for the field.

  Regards,
  Tom McGlynn
Lew - 03 Mar 2008 21:15 GMT
> Obviously, when you make a new class via inheritance, it gets it's own
> copy of the static variable.  So there will be one static for the parent
> class, and one for the child class.  The static is a "class variable"
> and since there are two classes (parent and child) there are two static
> variables.

This isn't exactly correct.  If the child class does not declare a hiding
static variable then there is only the parent-class variable.  There isn't by
default a duplicate version in the child class.

Signature

Lew

Eric Sosman - 03 Mar 2008 20:24 GMT
> I am curious - does the scope of static variables carry across
> different JAR files?

    You're asking a rather detailed question, so it would be
good to ask it in precise language.  What, exactly, do you
mean by "scope?"  You don't seem to be using the word in the
way the Java Language Specification does.

> Here's the issue:
>
[quoted text clipped - 4 lines]
> BaseClass has a static object (ObjectX).  Now, normally, this static
> object is static across all of the subclasses.  However...

    Precision again: What do you mean by "static object?"  As
far as I can see, objects cannot be static.  I *think* what you
mean is that BaseClass has a static member variable that refers
to an instance of the ObjectX class.

> These JAR files (AnotherPackage and EvenAnotherPackage) are being read
> in by a separate tool.  When ExtendedClassA and ExtendedClassB are
[quoted text clipped - 7 lines]
> from an academic standpoint.  Another group ran across this problem
> today.)

    A class is identified by its fully-qualified name *and* by
the ClassLoader instance that loaded it.  If two distinct loaders
load "net.worth.Zero" -- even if they load it from the very same
Zero.class file -- there will be two distinct classes both named
"net.worth.Zero" floating around in the JVM.  Something like an
IDE might find this convenient, because it would allow you to
edit and recompile Zero.java and then load the newly-compiled
class without restarting the JVM or somehow force-unloading the
old class.

    This "separate tool" you speak of may be using multiple class
loaders for one reason or another.  You could try getClass() on
both the ObjectX instances to find out whether they are actually
of different classes.

Signature

Eric.Sosman@sun.com

Jason Cavett - 04 Mar 2008 15:01 GMT
>      Precision again: What do you mean by "static object?"  As
> far as I can see, objects cannot be static.  I *think* what you
> mean is that BaseClass has a static member variable that refers
> to an instance of the ObjectX class.

You are correct.  Thanks for the correction.

>      A class is identified by its fully-qualified name *and* by
> the ClassLoader instance that loaded it.  If two distinct loaders
[quoted text clipped - 10 lines]
> both the ObjectX instances to find out whether they are actually
> of different classes.

Alright.  I figured it might be something like that.  I'm curious if
there is any possible way for static member variables to carry across
JVMs.  (I would guess that there isn't, but I figured I would ask.)
Eric Sosman - 04 Mar 2008 16:19 GMT
> [...]
> Alright.  I figured it might be something like that.  I'm curious if
> there is any possible way for static member variables to carry across
> JVMs.  (I would guess that there isn't, but I figured I would ask.)

    It seems far-fetched, but I won't rule it out because
I'm unfamiliar with RMI.  If there's a way two JVM's can
share the same (for some value of "same") object, I'd bet
that's where to hunt for it.

Signature

Eric.Sosman@sun.com

Adam Maass - 04 Mar 2008 08:03 GMT
>I am curious - does the scope of static variables carry across
> different JAR files?

Short answer: yes.

> Here's the issue:
>
[quoted text clipped - 16 lines]
> from an academic standpoint.  Another group ran across this problem
> today.)

Perhaps BaseClasses.jar is available to two different classloaders. "static"
is scoped on a per-classloader basis.

-- Adam Maass
Roedy Green - 04 Mar 2008 12:06 GMT
On Mon, 3 Mar 2008 11:23:07 -0800 (PST), Jason Cavett
<jason.cavett@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>BaseClass has a static object (ObjectX).  Now, normally, this static
>object is static across all of the subclasses.  However...

Please post some example code. There is no such thing as a "static
object".  If you want a singleton, it will have to be a static
reference in only one class.
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Jason Cavett - 04 Mar 2008 15:11 GMT
On Mar 4, 7:06 am, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:
> On Mon, 3 Mar 2008 11:23:07 -0800 (PST), Jason Cavett
> <jason.cav...@gmail.com> wrote, quoted or indirectly quoted someone
[quoted text clipped - 10 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

Yeah, I realize that I misspoke.  Thank you for the correction.  I,
instead, have a static member variable that refers to an object.

Anyway...the example code is pretty simple.

class Base {
 protected static String someInfo = null;

 public Base() {
    // instantiate
 }
}

class Child extends Base {

 public Child() {
   if(Base.someInfo == null) {
     someInfo = new String("String Here");
   }
 }
}

I have a couple other children that also extend base and, if someInfo
is null, they give the String their own value.  However, when I use
this 3rd party application to load up the different children classes,
someInfo is always null upon load and will be set with the string
specific to that child.

After doing some testing, I printed out the information of the String
and it is NOT the same String.  (AKA - Different classloaders are
probably being used to load up the children.)  What I'm wondering is
whether or not it is possible to stop this from happening.  AKA -
someInfo will refer to the same object across all classloaders.

Thanks
Lew - 04 Mar 2008 16:30 GMT
> class Base {
>   protected static String someInfo = null;
[quoted text clipped - 12 lines]
>   }
> }

This code runs an inherent risk of multiple instantiation of the 'someInfo'
variable, in a multi-threaded context.

> I have a couple other children that also extend base and, if someInfo
> is null, they give the String their own value.  

So what is 'someInfo' supposed to be when multiple children instantiate?  It's
a suspect pattern to have different children instantiate a parent-class static
member with different values.  Part of the problem is that it creates a
dependency between not only the parent to the child class, but between child
classes.  Now they have to be aware of the semantics of specific String (not
enum?!) values in a shared variable.

Another problem is that class loading in a different order can cause
non-deterministic behavior - on some runs the 'someInfo' will settle
eventually to one value, on other runs to a different value.

If multiple threads grab the class, even via the same class loader, each
thread could instantiate the variable to a different value and use that value
locally throughout its run.  The value change might not be visible to the
other or any subsequent thread.

It is likely that removing this static variable will be a better solution than
trying to get all that right.

Signature

Lew

Jason Cavett - 04 Mar 2008 19:37 GMT
> > class Base {
> >   protected static String someInfo = null;
[quoted text clipped - 40 lines]
> --
> Lew

Good points.  I'll make sure to pass them along.  (Again, this is not
my project...I'm just asking because I'm academically curious.)


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.