The static block is called twice, maybe multiple classloaders?

I have an EJB MDB with a static block inside it. I have used a static block to initialize some of the components only once the first time I run the application (i.e. when deploying). The EJB MDB is deployed on a separate server (My_Server) other than Admin_Server.

The problem is that the static block gets called twice!

  • First time: Right after deploying the EJB MDB (tied to My_Server).
  • Second time: after the JMS queue (which the MDB is associated with) receives the message.

Also, I printed the server name and pid and they are the same for both:

System.out.println("server name: " + System.getProperty("weblogic.Name"));
System.out.println("pid: " + ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);

      

I also noticed some strange behavior. Basically, I connected the Shutdown Hook (from inside the static block) to send me an email when the application exits.

  • I got a notification after I stopped My_Server.
  • I got a notification also after Admin_Server shutdown.

How can I solve this problem?


Additional Information:

Weblogic version: 10.3.0
EJB version: 3.0

      

+3


source to share


2 answers


This only happens if you have multiple classloaders. I would not have static initializers in EJB, rely on EJB lifecycle hooks, or export the initializer to an unmanaged class.

EJB 3.1 added annotations like @Singleton and @Startup, but unfortunately in 3.0 you got stuck with solutions for these guarantees.



Admin versus normal server behavior is fairly common as WebLogic deploys both of them usually. See this page for details .

For Weblogic completion hooks check this documentation page .

+7


source


Yes, the only way to get a static initializer executed more than once is if you've actually loaded two different copies of the class. And this can only happen if you have two different classloaders that load the class.



The way to prevent this is to arrange that the classes in question are loaded by the common classloader of the ancestors of the two classloaders. I don't know how you would do this with Weblogic, but for Tomcat, you will put the appropriate JAR files in a designated shared library directory that will be used by all web applications running in the container.

+4


source







All Articles