Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Libraries Runtime vs Compile Time

When setting up a Java web application using Tomcat as an application server I often get confused about when libraries are available. Through some discussion on Stack Overflow, I have learned that some libraries (.jar) files are available at runtime, while others are available at compile time. Often I will get errors and will resolve them by trial and error, placing jar files in different directories until the application runs or compiles. It was recently pointed out to me that you can make .jar libraries available at runtime via the WEB-INF/lib folder. I started thinking about this and had a few question. I have read up on this topic in the past and haven't found a source that puts the information into a context I easily understand and retain.

  1. Is there a compile time classpath and a runtime classpath you can set for a project?

    a. Is classpath even an applicable term for discussing libraries available at runtime?

  2. Is WEB-INF/lib the only way to make libraries available at runtime? What about the lib folder in Tomcat is this available at runtime?

  3. How does this relate to classloaders? I know that a hierarchy of classloaders is created. Are these strictly for Runtime operations?

like image 318
Kevin Bowersox Avatar asked May 03 '13 15:05

Kevin Bowersox


People also ask

Which is faster runtime or compile time?

Basically if your compiler can work out what you mean or what a value is "at compile time" it can hardcode this into the runtime code. Obviously if your runtime code has to do a calculation every time it will run slower, so if you can determine something at compile time it is much better.

What is difference between runtime and compile time dependency?

Compiletime dependencies are only the dependencies (other classes) which you use directly in the class you're compiling. Runtime dependencies covers both the direct and indirect dependencies of the class you're running.

Is JVM runtime or compile time?

JVM(Java Virtual Machine) acts as a run-time engine to run Java applications. JVM is the one that actually calls the main method present in a java code. JVM is a part of JRE(Java Runtime Environment).

What is the difference between compile time and runtime error?

A compile-time error generally refers to the errors that correspond to the semantics or syntax. A runtime error refers to the error that we encounter during the code execution during runtime. We can easily fix a compile-time error during the development of code. A compiler cannot identify a runtime error.


1 Answers

The compile classpath is the classpath used to compile your Java source files (using javac -cp ..., or your IDE). Every class referenced in the source file must be present in the compile classpath, else the compiler will complain that it can't find the class.

Once you have compiled the classes, you can run a program using them (using java -cp ...). Obviously, the libraries on which your source code depends directly should be in the runtime classpath. But that's not all. If you depend directly on CoolLibrary.jar, and this library internally depends on Guava.jar, then Guava.jar must also be in the runtime classpath, although it was not needed when compiling.

Webapps are a bit special. The servlet specification specifies that the classpath used to execute the webapp is composed by the WEB-INF/classes directory of the deployed webapp, and of all the jars contained in WEB-INF/lib. All the webapps also have access to the native servlet and JSP jars, which are directly provided by Tomcat. In reality, Tomcat's internal classes (like the implementation classes of the servlet-api interfaces) are also available to the webapp, but relying on these classes is not a good idea, since it would tie your webapp to tomcat.

Talking of the runtime classpath, in the case of a webapp, is a bit of a simplification. In reality, every webapp's classes are loaded dynamically by a specific classloader by tomcat. And this webapp classloader is a child of the tomcat's classloader. So, in theory, you could place the webapp jars in Tomcat's classpath directly, but this would mean that all the webapps would share these libraries, and that you would have problems undeploying and redeploying webapps. The goal of having a specific classloader per webapp is to be able to have, in the same JVM, an app relying on Guava 11.0, and another one relying on Guava 12.0, for example.

For more information about tomcat classloaders, read the documentation.

like image 169
JB Nizet Avatar answered Sep 30 '22 15:09

JB Nizet