我使用Java开发Web应用程序。当我将其部署到我的应用程序服务器(Jetty,Tomcat,JBoss,GlassFish等)时,将引发错误。我可以在stacktrace中看到此错误消息:
java.lang.ClassNotFoundException
要么
java.lang.NoClassDefFoundError
这是什么意思,我该如何解决?
这是什么意思?
首先,让我们看一下java.lang.ClassNotFoundException:
当应用程序尝试使用其字符串名称通过其字符串名称加载类时抛出: forName课堂教学中的方法Class。 findSystemClass课堂教学中的方法ClassLoader。 loadClass课堂教学中的方法ClassLoader。 但是找不到具有指定名称的类的定义。
当应用程序尝试使用其字符串名称通过其字符串名称加载类时抛出:
forName
Class
findSystemClass
ClassLoader
loadClass
但是找不到具有指定名称的类的定义。
通常,尝试以这种形式手动打开连接时会发生这种情况:
String jdbcDriver = "...'; //name of your driver Class.forName(jdbcDriver);
或者,当您引用属于外部库的类时, 奇怪的 是,当应用程序服务器尝试部署应用程序时,无法加载该类。
让我们来看看java.lang.NoClassDefFoundError(强调我的)的含义:
如果Java虚拟机或ClassLoader实例尝试加载类的定义(作为常规方法调用的一部分或使用新表达式创建新实例的一部分)而抛出,则找不到该类的定义。 当前编译的类在编译时就存在搜索到的类定义,但是不再可以找到该定义 。
如果Java虚拟机或ClassLoader实例尝试加载类的定义(作为常规方法调用的一部分或使用新表达式创建新实例的一部分)而抛出,则找不到该类的定义。
当前编译的类在编译时就存在搜索到的类定义,但是不再可以找到该定义 。
最后一部分说明了一切:该类在编译时即存在,即当我通过IDE编译应用程序时存在,但在运行时即部署应用程序时不可用。
我该如何解决?
在Java Web应用程序中,您的应用程序使用的所有第三方库都必须位于WEB-INF / lib文件夹中。确保将所有必需的库(jar)放置在此处。您可以轻松检查以下内容:
- <webapp folder> - WEB-INF - lib + jar1 + jar2 + ... - META-INF - <rest of your folders>
对于JDBC连接罐(MySQL,Derby,MSSQL,Oracle等)或Web MVC框架库(如JSF或Spring MVC),通常会出现此问题。
考虑到某些第三方库依赖于 其他 第三方库,因此必须将 它们全部 添加到WEB-INF / lib中才能使应用程序正常工作。RichFaces 4库就是一个很好的例子,您必须在其中手动下载和添加外部库。
Maven用户注意事项:除非将库设置为或provided,否则不应遇到这些问题。如果设置为,则负责将库添加到类路径中的某处。您可以在此处找到有关依赖范围的更多信息:依赖机制简介test``system``provided
provided
test``system``provided
如果必须在将要部署在您的应用程序服务器上的多个应用程序之间共享该库,例如用于两个应用程序的MySQL连接器,则还有另一种选择。无需将两个war文件分别使用各自的MySQL连接器库进行部署,而是将该库放置在服务器应用程序的公共库文件夹中,这将使该库位于所有已部署应用程序的类路径中。
此文件夹与应用程序服务器不同。
<tomcat_home>
<jboss_home>