java -verbose:class shows that the servlet is loaded but a static content is initialized only when the servlet is accessed

StackOverflow https://stackoverflow.com/questions/23066144

  •  03-07-2023
  •  | 
  •  

문제

I think that I'm getting something wrong here.

I have a simple servlet with a static block that prints some message. So as far as I understand the static block should be processed when the servlet class is first loaded into the jvm.

I am using embedded jetty and launch the jetty server with -verbose:class jvm option.

I can see in the output that the Servlet class is loaded long before I first access this servlet and see the messages.

But to my understanding the static block should be initialized right after the class is loaded. Where am I wrong here?

도움이 되었습니까?

해결책

The Java Language Specification states

The Java Virtual Machine dynamically loads, links and initializes classes and interfaces. Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation. Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed. Initialization of a class or interface consists of executing the class or interface initialization method <clinit> (§2.9).

That last part, the <clinit>, is where your static initializers are run.

The java launcher option you used

-verbose:class

simply

Displays information about each class loaded.

So your class is loaded as part of the web application loading the classpath entries, but it isn't initialized until Jetty instantiates it so that it can use the object to handle a request.

다른 팁

Now... when you say that the Servlet class is loaded, are you referring to your own class or to the javax.servlet.Servlet interface?

If you're not specifying <load-on-startup> and setting it to a non-zero value in the your servlet's declaration in web.xml, then jetty is just following the Servlet specification and not loading it until it's first used.


(Below is what I'd first written before I started looking at the Servlet spec and it may still be relevant depending on if you have <load-on-startup> set to a non-zero value)

According to the Java Specification §8.7

A static initializer declared in a class is executed when the class is initialized (§12.4.2).

§12.4.1 (the overview of §12.4.2) of the Java Specification says a class T is initialized when one of the following happens:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

So, if jetty never actually does anything with the class, the static initializer won't run

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top