Searching for an explanation for why my static initialization block wouldn't execute, I found that a static initializer in a class never executes if it references a final.
So I tried to work around this by removing the 'final' from MYWS_PROPS:
public class HibernateUtil {
public static String MYWS_PROPS = "/myws.properties";
private static final Logger LOG = Logger.getLogger(HibernateUtil.class.getName());
private static final SessionFactory sessionFactory = buildSessionFactory();
private static Properties sProps;
static {
try {
sProps = new Properties();
sProps.load(ServiceUtils.class.getResourceAsStream(MYWS_PROPS));
LOG.info("Loaded (from " + MYWS_PROPS + ") connection url: " + sProps.getProperty("dburl"));
}
catch (IOException e) {
LOG.severe("Cannot find properties file " + MYWS_PROPS);
}
}
private static SessionFactory buildSessionFactory() {
try {
Configuration config = new Configuration();
config = config.configure("resources/hibernate.cfg.xml");
config.setProperty("hibernate.connection.url", sProps.getProperty("dburl")); // <== NullPointerException!
SessionFactory session = config.buildSessionFactory();
return session;
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
}
But that static block still wouldn't execute!
What is the proper way to guarantee execution of a static block?
Update: All answers below mentioned the requirement to reference the class so that the static initialization will run. So I looked again at my stack trace and verified that the class is indeed referenced (otherwise, why would it throw an exception in that very same class method?)
Caused by: java.lang.ExceptionInInitializerError
at com.corp.dept.proj.myws.HibernateUtil.buildSessionFactory(HibernateUtil.java:76)
at com.corp.dept.proj.myws.HibernateUtil.<clinit>(HibernateUtil.java:38)
at com.corp.dept.proj.myws.ServicePortImpl.<init>(ServicePortImpl.java:82)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 70 more
Caused by: java.lang.NullPointerException
at com.corp.dept.proj.myws.HibernateUtil.buildSessionFactory(HibernateUtil.java:67)
... 77 more
But to be on the safe side, I tried the Class.forName suggestion:
Class.forName("com.corp.dept.proj.myws.HibernateUtil");
mProps.load(ServiceUtils.class.getResourceAsStream(HibernateUtil.MYWS_PROPS));
And that static block still wouldn't execute.
So I tried to explicitly instantiate it:
HibernateUtil justExecTheDarnStaticBlock = new HibernateUtil();
mProps.load(ServiceUtils.class.getResourceAsStream(HibernateUtil.MYWS_PROPS));
But that static block still wouldn't execute!
What am I missing here?