Maven Web项目部署Tomcat时JZMQ抛出NoClassDefFoundError
问题原因分析
- Maven system scope 特性限制:
system作用域的依赖被Maven标记为「由运行环境提供」,默认不会被打包到Web应用的WEB-INF/lib目录中。当部署到Tomcat时,Web应用的类加载器只能加载自身WEB-INF/lib和WEB-INF/classes下的类,因此找不到JZMQ jar里的org.zeromq.ZContext类。 - Tomcat类加载机制:你手动复制jar到
Tomcat/lib能解决问题,是因为这个目录下的jar由Tomcat的Common类加载器加载,所有Web应用都能共享访问,但这种方式脱离了Maven的项目依赖管理,不属于规范做法。
符合Maven规范的解决方法
方法1:将本地jar安装到本地Maven仓库
把JZMQ jar安装到本地Maven仓库后,就可以用普通的compile作用域依赖,无需system配置:
执行以下Maven命令(替换/path/to/your/zmq-3.1.0.jar为你的jar实际路径):
mvn install:install-file -Dfile=/path/to/your/zmq-3.1.0.jar -DgroupId=com.external.jzmq -DartifactId=zmq -Dversion=3.1.0 -Dpackaging=jar
然后修改pom.xml中的依赖为:
<dependency> <groupId>com.external.jzmq</groupId> <artifactId>zmq</artifactId> <version>3.1.0</version> </dependency>
这样Maven会自动将该jar打包到WEB-INF/lib中,Tomcat部署时就能正常加载类。
方法2:配置Maven War插件打包时包含system依赖
如果不想安装到本地仓库,可以通过maven-war-plugin配置,将本地system依赖的jar复制到WEB-INF/lib目录:
在pom.xml的build/plugins节点下添加:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> <configuration> <webResources> <resource> <!-- 指向你的外部jar所在目录 --> <directory>${external.lib.path}</directory> <!-- 打包时复制到war包的WEB-INF/lib下 --> <targetPath>WEB-INF/lib</targetPath> <!-- 指定要复制的jar文件 --> <includes> <include>*.jar</include> </includes> </resource> </webResources> </configuration> </plugin>
执行mvn package打包后,war包的WEB-INF/lib中会包含JZMQ jar,部署到Tomcat即可正常运行。
方法3:使用本地Maven私服(团队场景推荐)
如果是团队协作项目,可以搭建本地私服(如Nexus),将JZMQ jar上传到私服仓库,然后项目中直接引用私服的依赖,和普通Maven仓库依赖完全一致,既符合规范又方便团队共享。
内容的提问来源于stack exchange,提问作者Niji_K
相关产品推荐
相关产品推荐

