14

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

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

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

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

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

4

2 回答 2

18

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

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

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

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

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

于 2013-05-03T16:07:32.560 回答
1
  1. 在 eclipse 中,你有java build path在编译时包含库的,你有order and export,这是用于运行时的。

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

于 2013-05-03T15:56:08.020 回答