Tomcat 的 CLASSPATH 与 Java 不同,它不包含“.”。我该如何更改?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1612892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 17:49:42  来源:igfitidea点击:

Tomcat's CLASSPATH is different than Java's, and it does not include "." How do I change it?

javatomcatclasspathnoclassdeffounderror

提问by Murat Ayfer

I've been spending hours trying to figure out why I've been getting the java.lang.NoClassDefFoundError, and I've narrowed down the cause to Tomcat's classpath.

我花了几个小时试图弄清楚为什么我一直在得到java.lang.NoClassDefFoundError,并且我已经将原因缩小到 Tomcat 的类路径。

I used the code below to see what the path variables hold:

我使用下面的代码来查看路径变量的内容:

out.println("Classpath: '" + System.getProperty( "java.class.path" ) + "'" );
out.println("Ext dirs: '" + System.getProperty( "java.ext.dirs" ) + "'" );
out.println("Library path: '" + System.getProperty( "java.library.path" ) + "'" );
out.println("Path separator: '" + System.getProperty( "path.separator" ) + "'" );

And the output is:

输出是:

Classpath: ':/usr/local/tomcat/bin/bootstrap.jar'
Ext dirs: '/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/ext:/usr/java/packages/lib/ext'
Library path: '/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.16/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib'
Path separator: ':'

As you can see, Classpath does NOT start with "." as it's supposed to, and I believe that's why my program can't find the classes that I import from subdirectories in my webapp.

如您所见,Classpath 不以“.”开头。正如它应该的那样,我相信这就是为什么我的程序无法找到我从 webapp 中的子目录导入的类的原因。

To see where the classpath is set, i did grep -R bootstrap.jar /usr/local/tomcat/, and came accross this: CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar(in file /usr/local/tomcat/bin/catalina.sh)

要查看类路径的设置位置,我做了grep -R bootstrap.jar /usr/local/tomcat/,并且遇到了这个:(CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar在文件中/usr/local/tomcat/bin/catalina.sh

This makes me believe that for some reason $CLASSPATH is empty here. However, echo $CLASSPATHsuccessfully returns .:/usr/lib/jvm/java-6-sun/bin:/usr/local/tomcat/lib/servlet-api.jar

这让我相信由于某种原因 $CLASSPATH 在这里是空的。然而,echo $CLASSPATH成功返回.:/usr/lib/jvm/java-6-sun/bin:/usr/local/tomcat/lib/servlet-api.jar

Can anybody help pin down the problem here?

有人可以帮助确定这里的问题吗?



EDIT: All my servlet files are in WEB-INF/classes/controllers/, and the libraries i'm trying to load are class files in subdirectories. For example, if ClassName.classis in the WEB-INF/classes/controllers/packagename/ directory, I add package packagenameto the start of ClassName.java, and I import it using import packagename.*in someServlet.java.

编辑:我所有的 servlet 文件都在WEB-INF/classes/controllers/,我试图加载的库是子目录中的类文件。例如,如果ClassName.class位于 WEB-INF/classes/controllers/packagename/ 目录中,我将添加package packagename到 的开头ClassName.java,然后使用import packagename.*in导入它someServlet.java



EDIT2: I have solved my problem. My main issue was that, as written below, not using the correct package names. Also, I was trying to compile from inside the classes/controllers/directory, instead of compiling from classes/. Thank you all for your help!

EDIT2:我已经解决了我的问题。我的主要问题是,如下所述,没有使用正确的包名称。另外,我试图从classes/controllers/目录内部进行编译,而不是从classes/. 谢谢大家的帮助!

回答by jarnbjo

Classes required in a web application should be located within the web application in the WEB-INF/classes folder or packed in JAR files located in WEB-INF/lib. You should normally not use the servlet containers generic classpath settings for this, as you seem to attempt.

Web 应用程序中所需的类应位于 Web 应用程序的 WEB-INF/classes 文件夹中,或者打包在位于 WEB-INF/lib 的 JAR 文件中。您通常不应该为此使用 servlet 容器的通用类路径设置,正如您所尝试的那样。

回答by Pascal Thivent

Tomcat's classpath is not supposed to be starting with .. Actually, adding .to the classpath is just a convenient way to tell java to look for classes in the current directory without having to use -cpwhen using it on the command line.

Tomcat 的类路径不应该以.. 实际上,添加.到类路径只是告诉 java 在当前目录中查找类的一种便捷方式,而无需-cp在命令行上使用它时使用它。

Actually, in most case, you don't have to tweak Tomcat's classpath. To make Tomcat able to find your classes, what you need to do is to deploy your application as a standardized WAR (web archive) which has a specific layout. Something like that:

实际上,在大多数情况下,您不必调整 Tomcat 的类路径。为了让 Tomcat 能够找到您的类,您需要做的是将您的应用程序部署为具有特定布局的标准化 WAR(Web 存档)。类似的东西:

.
|-- WEB-INF
|   |-- classes
|   |   `-- com
|   |       `-- mycompany
|   |           `-- MyServlet.class
|   |-- lib
|   |   |-- bar.jar
|   |   `-- foo.jar
|   `-- web.xml
|-- application.jsp
|-- image.gif
`-- index.html

The WEB-INF/classesdirectory is where your compiled classes need to be, this is where Tomcat will look for them. If you place your classes in WEB-INF/classes/controllers, controllerswill be considered as part of the package name (which is likely not what you want). So you have two options:

WEB-INF/classes目录是编译类需要的位置,这是 Tomcat 将查找它们的位置。如果您将类放在WEB-INF/classes/controllers,controllers将被视为包名称的一部分(这可能不是您想要的)。所以你有两个选择:

  1. remove that controllersdirectory
  2. or add it to the package name.
  1. 删除那个controllers目录
  2. 或将其添加到包名称中。

But they are mutually exclusive, you can't have both.

但它们是相互排斥的,你不能同时拥有。

回答by erickson

CLASSPATHis not"supposed" to start with ".". Since its purpose is configuration of the runtime, it is free to take on any value you choose. Also note that using the CLASSPATHenvironment variable has been discouraged since Java 1.1 (released in early 1997)—at least 12 years.

CLASSPATH不是“应该”下手"."。由于其目的是配置运行时,因此可以随意采用您选择的任何值。另请注意,CLASSPATH自 Java 1.1(1997 年初发布)以来,不鼓励使用环境变量 - 至少 12 年。

The classpath of a web-application, on the other hand is well-specified. Move the contentsof the controllersdirectory (and any other invalid subdirectories) into WEB-INF/classes/, so that the package directory is an immediate child of classes.

另一方面,Web 应用程序的类路径是明确指定的。移动内容的的controllers目录(以及任何其他无效子目录)进入WEB-INF/classes/,使包目录的直接子classes