Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can one force execution of the static blocks of all the files in the application?

My goal is to have several classes to have a block of code that runs at the beginning of the program. Assume for a second that classes can be added to the project on a whim, and it will be impractical to have a static function that is called in the beginning of main.

I have tried to place the initialisation routine within the static block of those classes, and it works almost as expected, but not quite. These blocks get called only after something else in that class gets called. This can be demonstrated by the code below:

Test.java

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("Begin");
        new Another();
    }
}

Another.java

public class Another
{
    static
    {
        System.out.println("Another.static{}");
    }
    public Another()
    {
        System.out.println("Another.Another()");
    }
}

Another2.java

public class Another2
{
    static
    {
        System.out.println("Another2.static{}");
    }
    public Another2()
    {
        System.out.println("Another2.Another2()");
    }
}

The output is:

Begin
Another.static{}
Another.Another()

It can be seen that Another2 is assumed not to be there at all.

The question is: Is it possible to "kick" all the classes to execute their static blocks if they have them?

like image 501
v010dya Avatar asked Dec 09 '22 01:12

v010dya


2 Answers

Static blocks are executed if the class is loaded by the ClassLoader. So if you iterate over all your classes and load them via a class loader (no need to instantiate them!) every static block would get executed once.

On a deeper level I can't imagine a situation where you'd actually need this. This somehow hints to misdesigned class structures.

like image 190
Aron_dc Avatar answered Jan 20 '23 12:01

Aron_dc


This is not possible, since the VM will never attempt to load a class that isn't required by the code path traversed on its own. There are some obvious and some obscure reasons why its done that way.

Rule of thumb is: If there is no dependency to a class that is reachable (through code) from the programs entry point, then that class will never be loaded. Although reachable is quite lose, e.g. a reference can be established by just knowing a class' name (e.g. from a configuration file) and accessing that class with e.g. Class.forName().

What you cannot achieve is just dropping a class into the class path and have that class automagically become an additional entry point (which executing any static code without a cause from the main (and only) entry point would classify as).

like image 27
Durandal Avatar answered Jan 20 '23 10:01

Durandal