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
Tomcat's CLASSPATH is different than Java's, and it does not include "." How do I change it?
提问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 $CLASSPATH
successfully 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.class
is in the WEB-INF/classes/controllers/packagename/ directory, I add package packagename
to 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 -cp
when 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/classes
directory 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
, controllers
will 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
将被视为包名称的一部分(这可能不是您想要的)。所以你有两个选择:
- remove that
controllers
directory - or add it to the package name.
- 删除那个
controllers
目录 - 或将其添加到包名称中。
But they are mutually exclusive, you can't have both.
但它们是相互排斥的,你不能同时拥有。
回答by erickson
CLASSPATH
is 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 CLASSPATH
environment 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 controllers
directory (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
。