Java库运行时与编译时间

在使用Tomcat作为应用程序服务器设置Java Web应用程序时,我常常对库何时可用感到困惑。 通过对Stack Overflow的一些讨论,我了解到一些库(.jar)文件在运行时可用,而其他库在编译时可用。 通常我会收到错误并通过反复试验解决它们,将jar文件放在不同的目录中,直到应用程序运行或编译。 最近向我指出,您可以通过WEB-INF / lib文件夹在运行时使.jar库可用。 我开始考虑这个并提出一些问题。 我过去已经阅读过这个主题,并没有找到将信息放入我容易理解和保留的上下文中的来源。

  1. 是否有可以为项目设置的编译时类路径和运行时类路径?

    一个。 classpath是否是讨论运行时可用库的适用术语?

  2. WEB-INF / lib是在运行时使库可用的唯一方法吗? Tomcat中的lib文件夹在运行时可以使用吗?

  3. 这与类加载器有什么关系? 我知道创建了类加载器的层次结构。 这些是严格用于运行时操作吗?

编译类路径是用于编译Java源文件的类路径(使用javac -cp ...或IDE)。 源文件中引用的每个类都必须存在于编译类路径中,否则编译器会抱怨它无法找到该类。

编译完类后,可以使用它们运行程序(使用java -cp ... )。 显然,源代码所依赖的库应该位于运行时类路径中。 但这不是全部。 如果您直接依赖于CoolLibrary.jar,并且此库在内部依赖于Guava.jar,那么Guava.jar也必须位于运行时类路径中,尽管编译时不需要它。

Webapps有点特别。 servlet规范指定用于执行webapp的类路径由部署的webapp的WEB-INF / classes目录以及WEB-INF / lib中包含的所有jar组成。 所有webapps也可以访问由Tomcat直接提供的本机servlet和JSP jar。 实际上,Tomcat的内部类(比如servlet-api接口的实现类)也可用于webapp,但依赖这些类并不是一个好主意,因为它会将你的webapp绑定到tomcat。

在webapp的情况下,谈论运行时类路径是一种简化。 实际上,每个webapp的类都由tomcat由特定的类加载器动态加载。 这个webapp类加载器是tomcat的类加载器的子代。 因此,从理论上讲,您可以直接将webapp jar放在Tomcat的类路径中,但这意味着所有的Web应用程序都会共享这些库,并且您在取消部署和重新部署Web应用程序时会遇到问题。 每个webapp拥有一个特定的类加载器的目标是能够在同一个JVM中拥有一个依赖于Guava 11.0的应用程序,以及另一个依赖于Guava 12.0的应用程序。

有关tomcat类加载器的更多信息,请阅读文档 。

  1. 在eclipse中,你有java build path ,它包含编译期间的库,你有order and export ,这是运行时。

  2. 只有默认情况下可用的tomcat库