1

Good afternoon all,

I was wondering is there anyway to make the static block of a class run even when the class itself is not referenced?

I am aware that that it is lazily loaded such that simply calling any of the functions of that class will start initiating the class,

However I want the class to be initiated prior any calls, in other words I want it to run on JVM start regardless of whether or not it is referenced.

Preloading java classes/libraries at jar startup suggested a workaround, but its not really the solution I'm looking for (basically I don't want to need to do a Class.forName, I want it to be done on JVM start)

How would we go about doing it?

Community
  • 1
  • 1
Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 1
    Wondering for what are you doing ? You can load whatever you need in public static void main method, since this is the start point of any application. You have not got access to this code, use load-on-startup servlet(listener, filter) in case of Web Application. Or another approach if It's not web-app – Anton Feb 10 '12 at 14:09
  • @Umar I've got a library that does some *logging stuff*. Basically I want it to do some stuff on start (as long as the library is referenced), but without having to `MyLibrary.Init.Init()` at the start of the main method. – Pacerier Feb 10 '12 at 14:14
  • 2
    This is a bit circular. You want to load classes on start up without loading the classes on start up a particular way. It appears you want something which feels more automagical. It worth noting that aggressive loading of classes doesn't cause methods in those classes to compile. I would exercise the methods which are critical, and this would result in the classes being loaded. – Peter Lawrey Feb 10 '12 at 14:33
  • @PeterLawrey I'm not sure I understand you here, Yes I want to load the classes on start up without loading the classes on start up a particular way. For example, we don't bother if java.lang.X loads first or java.lang.Y loads first.. I just want them loaded. – Pacerier Feb 10 '12 at 15:12
  • In that cause you can create a file of classes you want to load (or generated it from a previous run of the application) and load them in a loop. However, if you are doing this for performance reasons, you are better of exercising the critical methods used to force them to compile. – Peter Lawrey Feb 10 '12 at 16:14
  • @PeterLawrey No it's not for performance reasons. I'd just want to make sure everything is loaded before timing them. Now I need to call a `Load()` in main once for each class which is really a mess when there's alot of classes. And we've got a problem that its a nuisance to maintain, e.g. when I add a new class I have to remember to add `X.Load()` and all these housekeeping issues.. I just want them All loaded before `main()` gets called. – Pacerier Feb 10 '12 at 17:58
  • If you want to time them, perform the action more than once and ignore the first time. I tend to ignore the first 10,000 to ensure all the code is compiled. – Peter Lawrey Feb 10 '12 at 19:20
  • @PeterLawrey Exactly, I mean isn't there some way we can tell the JVM to simply load everything so that we don't have to do these kind of things? – Pacerier Feb 10 '12 at 21:13
  • @Pacerier: 1. *everything* is quite a lot. How is the JVM supposed to know what it should load? If you take reflection into account then there is no way to predict what classes will be needed. 2. The JVM compiles code dynamically based on its actual usage and it has been known to recompile code when that usage changes. It makes no sense to compile code beforehand... – thkala Feb 10 '12 at 23:12
  • @thkala The JVM loads only what it knows. This includes the classes in the referenced jars, not those *dynamically* added. – Pacerier Feb 11 '12 at 21:28
  • Does this answer your question? [Preloading java classes/libraries at jar startup?](https://stackoverflow.com/questions/677739/preloading-java-classes-libraries-at-jar-startup) – Dave Jarvis Aug 31 '20 at 18:18

1 Answers1

2

If there is a way to do this, it would probably involve the use of JVM options, which is not exactly elegant or completely portable.

Using a wrapper class around your existing application might be a cleaner alternative, if all you need is for some class to be initialized before your actual application code is executed:

public class LoggedLauncher {
    public static void main(String[] args) {
        // Do whatever you need to initialize your logging class
        //
        // e.g. call a static method:
        //
        // MyLogger.init();

        // ...then start your application
        MyApplication.main(args);
    }
}

You might even use a bit of reflection so that the application class can be supplied as an argument to the wrapper, replacing the hard-coded reference. If you do so, don't forget to manipulate the args array so that the proper arguments will passed over to the main() method of your application.

thkala
  • 84,049
  • 23
  • 157
  • 201