当使用Tomcat作为应用程序服务器设置Java Web应用程序时,我常常对库何时可用感到困惑。通过对Stack Overflow的一些讨论,我了解到一些库(.jar)文件在运行时可用,而其他文件在编译时可用。通常我会得到错误并通过反复试验解决它们,将jar文件放在不同的目录中,直到应用程序运行或编译。最近向我指出,您可以通过WEB-INF / lib文件夹在运行时使.jar库可用。我开始考虑这个并提出一些问题。我过去已经阅读过这个主题,并且没有找到将信息放入我容易理解和保留的上下文中的来源。
是否有可以为项目设置的编译时类路径和运行时类路径?
一个。 classpath是否是讨论运行时可用库的适用术语?
WEB-INF / lib是否是在运行时使库可用的唯一方法? Tomcat中的lib文件夹在运行时可用吗?
这与类加载器有什么关系?我知道创建了类加载器的层次结构。这些是否严格用于运行时操作?
答案 0 :(得分:16)
compile classpath是用于编译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类加载器的更多信息,请阅读the documentation。
答案 1 :(得分:1)
在eclipse中,你有java build path
在编译期间包含库,你有order and export
,这是运行时的。
只有默认情况下可用的tomcat库