我有一个使用maven的webapp项目。
在项目的
pom.xml
文件中,有一个依赖元素引用驻留在本地文件系统中的 JZMQ jar 文件,如下所示:
<dependency>
<groupId>com.external.jzmq</groupId>
<artifactId>zmq</artifactId>
<version>3.1.0</version>
<scope>system</scope>
<systemPath>${external.lib.path}</systemPath>
</dependency>
其中
external.lib.path
是本地文件系统中的文件路径。
这个 JZMQ jar 文件是从 libzmq v4.1.6 和 JZMQ v3.1.0 构建的,如果有帮助的话。
然后将该项目加载到 Eclipse(x86_x64 Windows,2023-06)中,并应该在 Tomcat v7.0 服务器上运行。 问题是,当我尝试在 Tomcat 上加载并运行该项目时,它总是抛出以下错误:
java.lang.NoClassDefFoundError: org/zeromq/ZContext
at hub.wgw.AgentSingleton.<init>(AgentSingleton.java:45)
at hub.wgw.AgentSingleton.<clinit>(AgentSingleton.java:26)
at launch.TomcatStartup.contextInitialized(TomcatStartup.java:14)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5128)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5653)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.zeromq.ZContext
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1951)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1795)
... 12 more
(其中
hub.wgw.AgentSingleton
是该项目的一个课程)
我还应该指出,JZMQ 是这里唯一的选择。由于某些兼容性原因,我无法使用 JeroMQ 或 JCZMQ。同样,从 Maven Repo 获取 JZMQ 也是不可能的。
我几乎绝对确定这不是 JZMQ 方面的错误,因为我已经尝试在一个更简单的 Maven 项目中使用完全相同的 jar 文件来确保它正确运行,使用这里的片段:No jzmq in java.library.path
更准确地说,我创建了 2 个不同的、较小规模的 Maven 项目,它们使用 JZMQ 来回切换,并启动了这两个项目。它给了我预期的结果,没有任何错误或其他什么。
我想知道为什么当我可以在其他项目中使用它而没有问题时,这种情况不断发生,并且如果可能的话,想知道修复它的方法。
编辑:我可以通过简单地将有问题的 jar 文件复制粘贴到 Tomcat 的 lib 目录中来轻松解决问题,但这首先违背了使用 Maven 的目的。我想要一个解释,而不是一个解决方法。预先感谢。
如果依赖项的范围为
system
,则在最终构建中将忽略相关依赖项。这就是为什么尽管构建成功但它仍然不断抛出错误。
它在我的测试项目中运行良好的原因是它能够立即获取并使用 jzmq jar 文件,因为它在独立项目上运行,这与当前在 Tomcat 上运行的项目相反。所以,关键是添加如下内容:
<repositories>
<repository>
<id>com-external-jzmq</id>
<url>file://[local repository location]</url>
</repository>
</repositories>
这会设置一个本地存储库,然后可以使用它来查找其中的 jar 文件。然后,放置 jzmq jar 文件,使
(some path)\com.external.jzmq\zmq\3.1.0\zmq-3.1.0.jar
成为有效路径。
据我了解,此路径应与依赖项的组 ID、工件 ID 和版本匹配。即(group ID)\(artifact ID)\(version)
应该是路径。