Java 库运行时与编译时

2022-09-03 13:55:27

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

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

    一个。类路径甚至是讨论运行时可用的库的适用术语吗?

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

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


答案 1

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

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

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

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

有关 tomcat 类装入器的更多信息,请阅读文档


答案 2
  1. 在 eclipse 中,您有 在编译时包含库,并且您有 ,这是用于运行时的。java build pathorder and export

  2. 默认情况下只有雄猫库可用


推荐