Java 库运行时与编译时

2024-01-01

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

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

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

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

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


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

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

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

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

有关 tomcat 类加载器的更多信息,请阅读文档 http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 库运行时与编译时 的相关文章

随机推荐

  • 使用 Gradle 进行 git 描述的 Android 构建的自动版本控制

    我进行了广泛的搜索 但可能是由于 Android Studio 和 Gradle 的新颖性 我还没有找到任何关于如何执行此操作的描述 我想做基本上完全按照中描述的这个帖子 https stackoverflow com questions
  • 如何更改非英语单词的字体大小?

    In a Word 2007 https en wikipedia org wiki History of Microsoft Word Word 2007 document I manually select a sentence con
  • Git:如何从索引中删除文件而不从任何存储库中删除文件

    当你使用 git rm cached myfile 它不会从本地文件系统中删除 这是目标 但是 如果您已经对文件进行版本控制并提交 将其推送到中央存储库 并在使用该命令之前将其拉入另一个存储库 则它将从该系统中删除该文件 有没有办法只从版本
  • 字符串格式日期 - C# 或 VB.NET

    来自数据库的日期 需要格式为 mm dd yy For Each dr as DataRow in ds Tables 0 Rows Response Write dr CreateDate Next string Format 0 MM
  • 从 .h 文件 Visual Studio 创建 .cpp 文件

    我正在使用 Visual Studio 2008 我想知道是否可以根据给定的头文件创建 cpp 文件 因此 如果我有一个包含类和函数的 h 文件 它可以创建包含空白正文中输入的所有函数的代码文件 捷径 alt shift f10 VS201
  • 哪个版本的 gcc 支持 -Ofast 优化级别?

    我在 gcc 的文档中找到了 Ofast level opthttp gcc gnu org onlinedocs gcc Optimize Options html Optimize Options http gcc gnu org on
  • 重置/删除 Swing 中的边框

    这是一个非常具体的编码问题 最近 我被要求在工作中维护一些旧的 Java Swing GUI 代码 并遇到了这个问题 我已将我自己的名为 MyFilenameVerifier 的 InputVerifier 子类附加到 JTextField
  • Flutter - MultiProvider 如何与相同类型的提供者一起工作?

    例如 我试图同时获取多个流发出的数据 但其中 2 个或更多流发出相同类型的数据 比如说字符串 我的问题是 是否可以使用MultiProvider并使用多个StreamProvider 或任何提供者 但我对这种情况感兴趣 相同类型 同时仍然能
  • 流、视图、迭代器

    scala 中的流 视图 SeqView 和迭代器之间有什么区别 这是我的理解 它们都是惰性列表 流缓存值 迭代器只能使用一次 就不能回到起点重新评估价值吗 View 的值不会被缓存 但你可以一次又一次地评估它们 因此 如果我想节省堆空间
  • 如何更改asp.net core中的程序集信息?

    我想对我的 ASP NET Core 应用程序进行版本控制 我点击了这个链接 http www matthiaseinig de 2013 05 20 auto generate fileversion for all projects i
  • 计算每个场点位于轮廓内的频率

    我正在处理二维地理数据 我有一长串轮廓路径 现在我想确定域中的每个点有多少个轮廓 即我想计算轮廓表示的特征的空间频率分布 为了说明我想要做什么 这是第一个非常幼稚的实现 import numpy as np from shapely geo
  • 实例新类型(Golang)

    谁能告诉我如何从字符串创建 Type 的新实例 反映 有一些示例 但它们适用于较旧的 Go 1 之前的版本 语言 所以 如果我正确理解你的问题 你是在问当你只有类型名称作为字符串时如何创建一个对象 例如 您可能有一个字符串 MyStruct
  • java.io.File:访问文件名编码无效的文件

    因为 java io File 的构造函数采用 java lang String 作为参数 所以似乎无法告诉它在访问文件系统层时需要哪种文件名编码 因此 当您通常使用 UTF 8 作为文件名编码并且有一些文件名包含编码为 ISO 8859
  • Rails 将脚本作为后台作业执行

    我有一个已作为独立功能实现的 ruby 脚本 现在我想在我的 Rails 环境中执行这个脚本 但将其作为后台作业执行会增加难度 因为它需要大量的时间处理 添加delayed job gem后 我尝试调用以下句子 delay system r
  • 发现 ASP.NET Core 中的通用控制器

    我正在尝试创建一个像这样的通用控制器 Route api controller public class OrdersController
  • 如何摆脱 wasm_bindgen 包装结构中的生命周期

    目前我有一些类似于以下的代码 Lifetime of child is enforced to be valid as far as Parent is valid struct Child lt a gt some data i32 ph
  • MySQL可重复读隔离级别和丢失更新现象

    In 高性能 Java 持久性 https vladmihalcea com books high performance java persistence 书的6 3 3 3部分写道 在MySQL可重复读隔离级别中可能会出现丢失更新现象
  • 如何使用Python的加密模块加载RSA公钥

    我正在尝试使用加载公钥密码学 https cryptography io 模块 这就是密钥的样子 gt gt gt print pubkey BEGIN RSA PUBLIC KEY MIGfMA0GCSqGSIb3DQEBAQUAA4GN
  • 为什么 Scala 的 Symbol 不被接受作为列引用?

    尝试 Spark SQL 的示例 它们似乎工作得很好 除非需要表达式 scala gt val teenagers people where age gt 10 where age lt 19 select name
  • Java 库运行时与编译时

    当使用 Tomcat 作为应用程序服务器设置 Java Web 应用程序时 我经常对库何时可用感到困惑 通过 Stack Overflow 上的一些讨论 我了解到一些库 jar 文件在运行时可用 而另一些则在编译时可用 我经常会遇到错误 并