具有带静态变量的类的jar的多个实例的容器

时间:2021-08-20 16:50:32

I have a class A contained a static/singleton member called b.

我有一个类A包含一个名为b的静态/单例成员。

This class in included in a jar X, which appears at multiple locations.

此类包含在jar X中,它出现在多个位置。

My question is:

我的问题是:

  1. Are multiple copies of the jar X (and hence class A) present in the container having this codebase?
  2. jar X的多个副本(以及A类)是否存在于具有此代码库的容器中?

  3. If so, whenever I have an assignment A.b = 10;, the b member of which copy of A will get the assignment? I currently have a problem that seems to be arising from this scenario, whereby even after setting the static variable to some value, I get a null value in another part of the code that reads it. What's the right "pattern" to follow to avoid/overcome this problem (assuming my diagnosis is correct)?
  4. 如果是这样,每当我有一个作业A.b = 10;时,A的哪个副本的b成员将获得作业?我目前有一个似乎是由这种情况引起的问题,即使在将静态变量设置为某个值之后,我在读取它的代码的另一部分中得到一个空值。为避免/克服这个问题(假设我的诊断是正确的),遵循正确的“模式”是什么?

-KS

1 个解决方案

#1


0  

Here's a bit of an idea of what goes on with different ClassLoaders:

这里有一些关于不同ClassLoader的概念:

package test;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

public class StaticMemberTest {
    public static int count = 0;

    public static void main(String[] args) throws Exception {
        // my .class files are in bin, relative to where I run the test from
        File f = new File("./bin");
        URL u = f.toURL();

        ClassLoader classLoader1 = new URLClassLoader(new URL[] { u }, null);
        ClassLoader classLoader2 = new URLClassLoader(new URL[] { u }, null);

        Class class1 = classLoader1.loadClass("test.StaticMemberTest");
        System.out.println("class1=" + class1);
        System.out.println("class1.count=" + class1.getDeclaredField("count").get(null));

        Class class2 = classLoader2.loadClass("test.StaticMemberTest");
        System.out.println("class2=" + class2);
        System.out.println("class2.count=" + class2.getDeclaredField("count").get(null));

        class1.getDeclaredField("count").set(null, new Integer(99));

        System.out.println("class1.count=" + class1.getDeclaredField("count").get(null));
        System.out.println("class2.count=" + class2.getDeclaredField("count").get(null));

        System.out.println("class1.isAssignableFrom(class2)=" + class1.isAssignableFrom(class2));
        System.out.println("class2.isAssignableFrom(class1)=" + class2.isAssignableFrom(class1));

        Object ob1 = class1.newInstance();
        System.out.println("ob1=" + ob1);

        StaticMemberTest test = (StaticMemberTest) ob1;
    }
}

And the output

和输出

class1=class test.StaticMemberTest
class1.count=0
class2=class test.StaticMemberTest
class2.count=0
class1.count=99
class2.count=0
class1.isAssignableFrom(class2)=false
class2.isAssignableFrom(class1)=false
ob1=test.StaticMemberTest@35ce36
Exception in thread "main" java.lang.ClassCastException: test.StaticMemberTest
    at test.StaticMemberTest.main(StaticMemberTest.java:37)

So you can see that the class names are the same, and both counts start off at zero. But you can set the static variable values independently.

所以你可以看到类名是相同的,两个计数都从零开始。但您可以单独设置静态变量值。

Also, the isAssignableFrom tests show that the classes are not the same as far as the JVM is concerned.

此外,isAssignableFrom测试表明,就JVM而言,这些类并不相同。

And finally, when I try a cast that should work, it fails. Because the ClassLoader that loaded class1 was not in the same ClassLoader hierarchy as the ClassLoader that was used to run the test. So the object ob1 it created was not compatible with the Class of the test itself.

最后,当我尝试一个应该有效的演员阵容时,它会失败。因为加载class1的ClassLoader与用于运行测试的ClassLoader不在同一ClassLoader层次结构中。因此它创建的对象ob1与测试本身的类不兼容。

#1


0  

Here's a bit of an idea of what goes on with different ClassLoaders:

这里有一些关于不同ClassLoader的概念:

package test;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

public class StaticMemberTest {
    public static int count = 0;

    public static void main(String[] args) throws Exception {
        // my .class files are in bin, relative to where I run the test from
        File f = new File("./bin");
        URL u = f.toURL();

        ClassLoader classLoader1 = new URLClassLoader(new URL[] { u }, null);
        ClassLoader classLoader2 = new URLClassLoader(new URL[] { u }, null);

        Class class1 = classLoader1.loadClass("test.StaticMemberTest");
        System.out.println("class1=" + class1);
        System.out.println("class1.count=" + class1.getDeclaredField("count").get(null));

        Class class2 = classLoader2.loadClass("test.StaticMemberTest");
        System.out.println("class2=" + class2);
        System.out.println("class2.count=" + class2.getDeclaredField("count").get(null));

        class1.getDeclaredField("count").set(null, new Integer(99));

        System.out.println("class1.count=" + class1.getDeclaredField("count").get(null));
        System.out.println("class2.count=" + class2.getDeclaredField("count").get(null));

        System.out.println("class1.isAssignableFrom(class2)=" + class1.isAssignableFrom(class2));
        System.out.println("class2.isAssignableFrom(class1)=" + class2.isAssignableFrom(class1));

        Object ob1 = class1.newInstance();
        System.out.println("ob1=" + ob1);

        StaticMemberTest test = (StaticMemberTest) ob1;
    }
}

And the output

和输出

class1=class test.StaticMemberTest
class1.count=0
class2=class test.StaticMemberTest
class2.count=0
class1.count=99
class2.count=0
class1.isAssignableFrom(class2)=false
class2.isAssignableFrom(class1)=false
ob1=test.StaticMemberTest@35ce36
Exception in thread "main" java.lang.ClassCastException: test.StaticMemberTest
    at test.StaticMemberTest.main(StaticMemberTest.java:37)

So you can see that the class names are the same, and both counts start off at zero. But you can set the static variable values independently.

所以你可以看到类名是相同的,两个计数都从零开始。但您可以单独设置静态变量值。

Also, the isAssignableFrom tests show that the classes are not the same as far as the JVM is concerned.

此外,isAssignableFrom测试表明,就JVM而言,这些类并不相同。

And finally, when I try a cast that should work, it fails. Because the ClassLoader that loaded class1 was not in the same ClassLoader hierarchy as the ClassLoader that was used to run the test. So the object ob1 it created was not compatible with the Class of the test itself.

最后,当我尝试一个应该有效的演员阵容时,它会失败。因为加载class1的ClassLoader与用于运行测试的ClassLoader不在同一ClassLoader层次结构中。因此它创建的对象ob1与测试本身的类不兼容。