Search code examples
javaclassprojectsstatic-initialization

Java - static initializers in imported projects


So I have two projects A and B, and project B is imported in project A, and in project B I want to initialize some objects which have static initializers. The problem is, they aren't getting called (already tested with final keyword, does not help).

So I actually want to have a small system and it should go this way (every class decribed here are in project B):

  • class A is a main class in which you can call a method addClassToLoad()* to add other classes (which will be "loaded" when method start() in class A will be called);
  • classes B, C and D call method addClassToLoad() from its static initializer;
  • when some class from project A calls a method start(), class A lists all classes it has gotten and calls a method onLoad() (explained in *).

And every method is static, so it's meant to be only one (no "instancing").

Saddly, static initializers aren't getting called.

And the question is: do I do something wrong (or maybe it is not possible at all) or maybe there is another way to do this small system? (I just don't really want to write in class A about every class, which must be loaded at start() method)

*addClassToLoad() takes an interface which has one method onLoad(), so it is getting called when method start() is called in class A

In code version:

class A:

public class A {
    private static ArrayList<ClassToLoad> classesToLoad;

    public static void addClassToLoad(ClassToLoad c) {
        if (classesToLoad == null)
            classesToLoad = new ArrayList<ClassToLoad>();
        classesToLoad.add(c);
    }

    public static void start() {
        for (ClassToLoad c : classesToLoad) {
            c.onLoad();
        }
    }
}

class B (and others (C, D etc.) like this one):

public class B {

    static {
        A.addClassToLoad(new ClassToLoad() {
            public void onLoad() {
                load();
            }
        });
    }

    private static void load() {
        // do something here on load ...
    }
}

class ClassToLoad:

public interface ClassToLoad {
    public void onLoad();
}

Solution

  • So it seems it's not possible for me to execute those static blocks, so I added every class, which I need to load, into class A, and that way they're actually loading without any problems (in project B). And in project A I need to add other classes, which I need to load, in the main class, obviously.

    So I made those classes as Singletons, so they're actually loaded and are ready for "main" loading, launching and disposing. So the adding class looks like this:

    A.addClassToLoad(B.getInstance());
    

    I used class ClassToLoad as a generic class to load (sounds funny), though I renamed it to SystemCycle.

    So the code as an example of class B now looks like this:

    public class B implements SystemCycle {
        private static B instance = new B();
    
        private B() {}
    
        public static void getInstance() {
            return instance;
        }
    
        public void onLoad() { /* some code here */ }
        public void onLaunch() { /* some code here */ }
        public void onDispose() { /* some code here */ }
    
    }
    

    And SystemCycle class looks now like this:

    public interface SystemCycle {
    
        public void onLoad();
        public void onLaunch();
        public void onDispose();
    
    }
    

    Well, that was obvious, because of example of class B.

    And I even made small checking system, so if the user tries to call one of these methods, it will be ignored, as the class implementing SystemCycle checks whether the class A is actually loading, launching or disposing at that moment. But if not, it just can do return. (though if the usermade class doesn't check that, it can be abused by other usermade class).

    P.S. addClassToLoad in my project is actually called addSystemToLoad, so I made it here this way to make an example easier to understand.

    Small edit: I even tried something to do with annotations first, but even that thing didn't help me.