简体   繁体   English

Maven项目中的蚂蚁罐库

[英]Ant jar library in maven project

We started to develop a new web application project and decided to use Maven. 我们开始开发一个新的Web应用程序项目,并决定使用Maven。 This project will use some older internal ant based jar library, so I decided to use Nexus to create our internal repository. 该项目将使用一些较旧的基于内部ant的jar库,因此我决定使用Nexus创建内部存储库。 I deployed the library to Nexus and linked pom.xml to the new repository and set the dependency to newly created artefact. 我将库部署到Nexus,并将pom.xml链接到新的存储库,并将依赖项设置为新创建的工件。 Maven builds war without problems, I can deploy it on server and launch. Maven可以毫无问题地进行战争,我可以将其部署在服务器上并启动。 So far, everything is working fine. 到目前为止,一切正常。

But now, when I try to call some code of the library, I got a NoClassDefFoundError exception. 但是现在,当我尝试调用该库的某些代码时,出现了NoClassDefFoundError异常。

java.lang.NoClassDefFoundError: HTTPClient/HTTPConnection
at com.logica.imfplus.authentication.client.HttpConnection.connect(HttpConnection.java:217)
at com.logica.imfplus.authentication.client.HttpConnection.<init>(HttpConnection.java:135)
at com.logica.imfplus.authentication.client.LoginController.getResponse(LoginController.java:402)
at com.logica.imfplus.authentication.client.LoginController.login(LoginController.java:169)
at com.logica.imfplus.authentication.client.AuthClientAPI.internalLogin(AuthClientAPI.java:416)
at ...
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

Caused by: java.lang.ClassNotFoundException: HTTPClient.HTTPConnection
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
... 38 more

I googled little bit and added dependency manually to the missing library. 我搜索了一下,然后手动将依赖项添加到缺少的库中。

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.3.3</version>
</dependency>

But I got another various NoClassDefFoundError exceptions. 但是我还有另一个各种NoClassDefFoundError异常。 All problem seems to be more complex. 所有问题似乎更加复杂。

I think I understand the problem: The jar library has it's own internal dependencies defined by ant, but they are not visible for maven so they are still missing. 我想我理解问题所在:jar库具有由ant定义的自己的内部依赖关系,但是它们对于maven不可见,因此仍然丢失。 But I don't know, how to solve it. 但我不知道如何解决。

If I am right, I was thinking of examining all those internal dependencies manually and add them to pom.xml. 如果我是对的,我正在考虑手动检查所有这些内部依赖项,并将它们添加到pom.xml中。 But it seems like dirty solution and I don't feel safe about it. 但这似乎是肮脏的解决方案,对此我感到不安全。 I also don't want to add mess to my pom.xml, if I don't have to. 我也不想在我的pom.xml中添加混乱,如果不需要的话。 Is there any cleaner way, how to do it? 有没有更清洁的方法,该怎么做? Can maven examine and resolve internal dependencies of non-mavenized jar library defined earlier by ant? Maven可以检查并解析由ant先前定义的非未修饰的jar库的内部依赖性吗?

I am still learning with maven, so solution is maybe obvious. 我仍在学习Maven,因此解决方案可能很明显。 I still didn't find anything useful. 我仍然没有发现任何有用的东西。


EDIT: Solution found and working. 编辑:找到解决方案并正常工作。 I created a new pom.xml with defined dependencies as suggested and (manually) uploaded to Nexus. 我根据建议创建了一个新的pom.xml,并定义了相关性,并(手动)将其上传到了Nexus。 Now transitive dependencies are correctly resolved and downloaded by maven. 现在,传递性依赖关系已由maven正确解析并下载。 Here it is fyi. 这是菲。 (There was in fact only one dependency to define.) (实际上只有一个依赖项可以定义。)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.logica.imfplus.authentication</groupId>
    <artifactId>authenticationClient</artifactId>
    <packaging>jar</packaging>
    <version>1.3.1.0_8</version>
    <name>IMFplus authenticationClient</name>

    <dependencies>
        <dependency>
            <groupId>net.sf.grinder</groupId>
            <artifactId>grinder-httpclient</artifactId>
            <version>3.9.1</version>
        </dependency>
    </dependencies>
</project>

I still got some ClassNotFoundException, but it is probably caused by some collision in libraries, this is different story. 我仍然有一些ClassNotFoundException,但这可能是由库中的某些冲突引起的,这是另外一回事了。

The ideal way to do this is to rebuild your internal library with a pom of its own where you specify all its dependencies. 理想的方法是使用内部pom重建内部库,并在其中指定所有依赖项。 Then you should point that pom.xml to your nexus repository and deploy it (as in mvn deploy ). 然后,您应该将该pom.xml指向您的nexus存储库并进行部署(如在mvn deploy )。 This way, the pom.xml will get published too in nexus and any application using the maven dependency will download too every dependency that your legacy library carries with it. 这样,pom.xml也将在关系中发布,并且任何使用maven依赖项的应用程序都将下载旧版库所附带的所有依赖项。

In general, you should only be deploying your internal artifacts to your internal Nexus. 通常,您只应将内部构件部署到内部Nexus。 3rd party artifacts should be obtained via your internal Nexus that acts as a Proxy Repository to the public Nexus repositories. 应该通过您的内部Nexus(作为公共Nexus信息库的代理信息库)获取第三者工件。 These days, you can normally find most 3rd party artifacts in a public repository somewhere. 如今,通常您可以在某个地方的公共存储库中找到大多数第三者工件。

When it comes to Maven, it uses what's called transitive dependencies , which in short means that if artifact A depends on artifact B and you create a new artifact that depends on A, you'll also depend on B. 当涉及到Maven时,它使用了所谓的传递依赖关系 ,简而言之,这意味着如果工件A依赖工件B,并且您创建了一个依赖A的新工件,那么您还将依赖B。

For this to work it's important that artifact A is built with Maven because the dependencies are captured at build time. 为此,使用Maven构建工件A很重要,因为依赖关系是在构建时捕获的。 The alternative is that you manually deploy the pre-built artifact , in which case the dependency information has been lost and you'll have to define it yourself by creating a pom for the 3rd party artifact. 另一种选择是,您手动部署预构建的工件 ,在这种情况下,依赖项信息已丢失,您将必须通过为第三方工件创建pom来自己定义它。

Assuming the dependencies are correct (you can list them with mvn dependency:list ), when you build a WAR with Maven, all the compile and runtime dependencies will be included in the WEB-INF/lib directory. 假设依赖关系正确(可以使用mvndependency:list列出它们),当使用Maven构建WAR时,所有编译和运行时依赖关系都将包含在WEB-INF / lib目录中。

A good solution for this problem is to create a pom.xml for the ant project that declares the dependencies correctly and use the aether ant tasks to deploy the jar from the Ant build to the Nexus instance. 一个很好的解决方案是为ant项目创建一个pom.xml,以正确声明依赖项,并使用ether ant任务将jar从Ant版本部署到Nexus实例。

Then you can use the Ant built Jar from Maven like any other dependency and it will even have the correct transitive dependencies managed automaticall.y 然后,您可以像其他任何依赖项一样使用Maven的Ant构建的Jar,它甚至将具有正确的可传递依赖项,并由automaticall.y管理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM