2

I have a situation where I have a registry class to which certain classes have to register themselves for the system. Since I'm writing an API I can't necessarily know which these classes are before runtime, so my solution is using a static block within each class for it to register itself.

The problem is of course that the static block isn't run until each class is initialized, and because there are no explicit references to each individual class, they never are initialized. Catch-22.

So, is there any way or annotation to make sure that a class is initialized at startup without referring to it explicitly?

mikek
  • 1,555
  • 17
  • 30
  • Can you call `Class.forName("com.example.MyClass")` to ensure that the class is initialised? There is also another `Class.forName` method that takes an `initialize` flag as a parameter – Simon C Oct 28 '11 at 07:45
  • As I said, my code isn't aware of the class beforehand. If I could call it explicitly, I wouldn't have a problem =) – mikek Oct 28 '11 at 08:13
  • Can you use a Java property or configuration file to list the class names so that you can load them yourself? Or, can you use a `@Singleton` bean annotation that *is a new kind of session bean that is guaranteed to be instantiated once for an application in a particular Java Virtual Machine (JVM)* ? – Simon C Oct 28 '11 at 09:17
  • @Singleton is sadly EJB3.1, so outside of my scope :/ – mikek Oct 28 '11 at 10:38

2 Answers2

1

Spring for instance, does this using the @Component annotation, or any if its subclasses, to scan for annotated classes at runtime. You could use spring for this, implement such functionality for yourself, or use a dedicated library such as scannotation.

If you decide to look into spring, you can use the bean ClassPathScanningCandidateComponentProvider standalone to scan for classes with a given annotation.

Johan Sjöberg
  • 47,929
  • 21
  • 130
  • 148
1

If you're not running in some sort of container environment (e.g. using OSGI,Spring,Guice etc..), there's no general way yet without making it explicit. You can take the approach of JDBC, in which the user of a particular JDBC driver library have to make sure the driver is initialized before use,

i.e. someone have to run e.g. Class.forName("org.postgresql.Driver"); , which will load the org.postgresql.Driver class. In that class you can have a static initializer which also loads/registers all the other classes you need.

nos
  • 223,662
  • 58
  • 417
  • 506
  • EJB3.0 is the only container that I can guarantee. These classes aren't explicitly in EJB context though. – mikek Oct 28 '11 at 08:14
  • 1
    EJB3 doesn't have an initializer framework either, unless you want to count the servletcontextlistener. – Renan Oct 28 '11 at 08:18