简体   繁体   English

Java库运行时与编译时

[英]Java Libraries Runtime vs Compile Time

When setting up a Java web application using Tomcat as an application server I often get confused about when libraries are available. 当使用Tomcat作为应用程序服务器来设置Java Web应用程序时,我常常对何时可用库感到困惑。 Through some discussion on Stack Overflow, I have learned that some libraries (.jar) files are available at runtime, while others are available at compile time. 通过有关堆栈溢出的讨论,我了解到一些库(.jar)文件在运行时可用,而另一些在编译时可用。 Often I will get errors and will resolve them by trial and error, placing jar files in different directories until the application runs or compiles. 通常,我会得到错误,并会通过反复试验来解决它们,将jar文件放在不同的目录中,直到应用程序运行或编译为止。 It was recently pointed out to me that you can make .jar libraries available at runtime via the WEB-INF/lib folder. 最近向我指出,您可以在运行时通过WEB-INF / lib文件夹使.jar库可用。 I started thinking about this and had a few question. 我开始考虑这个问题,并提出了一些问题。 I have read up on this topic in the past and haven't found a source that puts the information into a context I easily understand and retain. 过去,我已经阅读了有关该主题的信息,但是没有找到将信息置于易于理解和保留的上下文中的资源。

  1. Is there a compile time classpath and a runtime classpath you can set for a project? 您可以为项目设置编译时类路径和运行时类路径吗?

    a. 一种。 Is classpath even an applicable term for discussing libraries available at runtime? 类路径甚至是讨论库的适用术语吗?

  2. Is WEB-INF/lib the only way to make libraries available at runtime? WEB-INF / lib是使库在运行时可用的唯一方法吗? What about the lib folder in Tomcat is this available at runtime? 在运行时可以使用Tomcat中的lib文件夹吗?

  3. How does this relate to classloaders? 这与类加载器有何关系? I know that a hierarchy of classloaders is created. 我知道创建了一个类加载器的层次结构。 Are these strictly for Runtime operations? 这些严格用于运行时操作吗?

The compile classpath is the classpath used to compile your Java source files (using javac -cp ... , or your IDE). 编译类路径是用于编译Java源文件的类路径(使用javac -cp ...或您的IDE)。 Every class referenced in the source file must be present in the compile classpath, else the compiler will complain that it can't find the class. 源文件中引用的每个类都必须存在于编译类路径中,否则编译器会抱怨找不到该类。

Once you have compiled the classes, you can run a program using them (using java -cp ... ). 编译完类之后,就可以使用它们运行程序(使用java -cp ... )。 Obviously, the libraries on which your source code depends directly should be in the runtime classpath. 显然,源代码直接依赖的库应该在运行时类路径中。 But that's not all. 但这还不是全部。 If you depend directly on CoolLibrary.jar, and this library internally depends on Guava.jar, then Guava.jar must also be in the runtime classpath, although it was not needed when compiling. 如果您直接依赖于CoolLibrary.jar,并且此库内部依赖于Guava.jar,那么Guava.jar也必须位于运行时类路径中,尽管在编译时不需要。

Webapps are a bit special. Webapp有点特别。 The servlet specification specifies that the classpath used to execute the webapp is composed by the WEB-INF/classes directory of the deployed webapp, and of all the jars contained in WEB-INF/lib. Servlet规范指定,用于执行webapp的类路径由部署的webapp的WEB-INF / classes目录以及WEB-INF / lib中包含的所有jar组成。 All the webapps also have access to the native servlet and JSP jars, which are directly provided by Tomcat. 所有的Web应用程序都可以访问由Tomcat直接提供的本地servlet和JSP jar。 In reality, Tomcat's internal classes (like the implementation classes of the servlet-api interfaces) are also available to the webapp, but relying on these classes is not a good idea, since it would tie your webapp to tomcat. 实际上,Tomcat的内部类(例如servlet-api接口的实现类)也可用于webapp,但是依靠这些类不是一个好主意,因为它将把您的webapp绑定到tomcat。

Talking of the runtime classpath, in the case of a webapp, is a bit of a simplification. 对于Webapp,谈论运行时类路径有点简化。 In reality, every webapp's classes are loaded dynamically by a specific classloader by tomcat. 实际上,每个Webapp的类都是由tomcat的特定类加载器动态加载的。 And this webapp classloader is a child of the tomcat's classloader. 这个webapp类加载器是tomcat类加载器的子类。 So, in theory, you could place the webapp jars in Tomcat's classpath directly, but this would mean that all the webapps would share these libraries, and that you would have problems undeploying and redeploying webapps. 因此,从理论上讲,您可以将Web应用程序jar直接放置在Tomcat的类路径中,但这将意味着所有Web应用程序都将共享这些库,并且在取消部署和重新部署Web应用程序时会遇到问题。 The goal of having a specific classloader per webapp is to be able to have, in the same JVM, an app relying on Guava 11.0, and another one relying on Guava 12.0, for example. 例如,每个Web应用程序都有一个特定的类加载器,其目的是能够在同一个JVM中拥有一个依赖于Guava 11.0的应用程序,以及另一个依赖于Guava 12.0的应用程序。

For more information about tomcat classloaders, read the documentation . 有关tomcat类加载器的更多信息,请阅读文档

  1. in eclipse, you have the java build path which include the libraries during compile time, and you have order and export , which is for the runtime. 在eclipse中,您具有在编译时包括库的java build path ,并且具有用于运行时的order and export

  2. only the tomcat libraries available by default 默认情况下仅tomcat库可用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM