2013-05-03 123 views
12

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

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

    a。 Classpath甚至是讨论在运行时可用的库的适用术语吗?

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

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

+0

“是否有编译时类路径和可以为项目设置的运行时类路径?”我不认为“项目”是Tomcat的概念。你在想Web应用程序还是Eclipse(或其他IDE)项目? – leonbloy 2013-05-03 16:00:23

+0

我应该将这个范围做得更好,我将Eclipse和Tomcat考虑在内。 – 2013-05-03 16:01:42

回答

15

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

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

Web应用程序有点特别。 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的classpath中,但这意味着所有的webapps都会共享这些库,并且您在取消部署和重新部署webapps时会遇到问题。例如,每个webapp拥有一个特定的类加载器的目标是能够在同一个JVM中使用一个依赖于Guava 11.0的应用程序,而另一个依靠Guava 12.0。请参阅the documentation

+0

因此,当我在Eclipse中打开Tomcat服务器并将其类路径设置为运行时类路径时?无论如何要设置每个应用程序?我想通过在特定于应用程序的运行时类路径中指定这些jar来避免100mb战争文件。 – 2013-05-03 16:10:43

+2

重要的是部署的Web应用程序。默认情况下,eclipse WTP项目中的WebContent/WEB-INF/lib下的所有jar都会自动添加到编译类路径(Eclipse调用构建路径)中,并且也会使用webapp在WEB-INF/lib,由Eclipse部署者。因此,在一个典型的eclipse Web项目中,您可以将Web应用程序所需的所有库放入WEB-INF/lib中,并将所有在运行时不需要的库(例如单元测试库)放入另一个目录中,并添加到建立路径。通常没有理由混淆Tomcat的内部类路径。 – 2013-05-03 16:14:21

1
  1. 在eclipse

    ,你有java build path,其中包括在编译时库,和你有order and export,这对于运行。

    只有
  2. tomcat的默认提供

+1

在Eclipse的'Order and Export'选项卡中,它表示'Exported entries are contribute to dependent projects'并不意味着依赖项目会将这些库用于编译?你确定它涉及到服务器的运行时? – 2013-05-03 16:03:29