让我先解释必要的库的含义。我使用Google App Engine for Java和官方Google Maven Plugin创建我的第一个项目,Maven作为打包解决方案(或者整个Java开发)的主要问题是,如果依赖树生长太多,释放过程可能会更难。
让我用一个例子来说明。让我们从Jackson JSON库开始(它是一个很好的起点,因为它没有父依赖项),现在有人制作一个JSON-RPC库并使用Jackson进行JSON序列化/反序列化。想象一下,这个库不仅提供了JSON-RPC客户端实现,还提供了服务器,这意味着该lib的POM将添加一些Java EE相关库,例如我们Jetty作为依赖项。
指南可能会说应用程序应该分为模块或将服务器相关的deps标记为可选,但是你知道很多人都不遵守这些标准。
现在有人为他/她的项目需要一个JSON-RPC客户端,称之为Project X,并使用上面提到的lib,在编译时没有问题,Maven将成功下载所需的libs并且应用程序将编译很好,但问题来自那个人想要发布应用程序。 哪些依赖项应该与软件包一起分发(例如在lib文件夹中)?
实际上发生在我身上的事情,我对Maven并不太熟悉,所以我使用Eclipse Runnable Jar Exporter生成jar文件,将所有maven库复制到lb子文件夹,所以我做的解决方法是删除看起来不必要的库,然后测试应用程序是否仍在工作。如果有没有执行的类,据我所知它们没有被ClassLoader
加载,所以可以省略它们并且是不必要的
我现在无法使用相同的技巧,因为场景要复杂得多,我们谈的是Java Web应用程序,而不是像其他应用程序那样的桌面应用程序,而我想要包含的库是Liquid模板Engine,它使用ANTLR框架为JSON处理程序生成解析器和Jackson,为HTML解析生成Jsoup。
应该在WEB-INF / lib文件夹中打包哪些库?我确信我需要Jackson进行JSON解析,但我对Jsoup不太确定,那么ANTLR是什么,它是必要的还是仅在编译时使用?
更新我认为我需要重新制定我的问题,实际上我想要的是确定应用程序真正需要哪些依赖项,并将其打包成app WEB-INF / lib文件夹
解决方案:一旦应用程序位于Google App Engine生产环境中,似乎已将使用打包在Web应用程序的WAR文件中的POM文件检索必要的依赖项,并且appengine:update
目标可能只包装那些无法从maven中央存储库中检索到的依赖项,因此无需担心这一点。
感谢David指出这一点。
答案 0 :(得分:0)
您可以排除任何传递依赖。
对于您的情况,要从此json-rpc库中删除jetty,您需要:
<dependency>
<groupId>com.somecomp</groupId>
<artifactId>jsonrpclib</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
</exclusions>
</dependency>
请参阅文档:http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
答案 1 :(得分:0)
你应该检查Maven的dependency scopes。以下是文档摘录:
有6个范围:
- 编译这是默认范围,如果未指定,则使用此范围。编 依赖项在项目的所有类路径中都可用。 此外,这些依赖项将传播到依赖项目。
- 提供这很像编译,但表示您期望JDK 或者在运行时提供依赖性的容器。例如,何时 您可以为Java Enterprise Edition构建Web应用程序 设置对Servlet API和相关Java EE API的依赖 提供范围是因为Web容器提供了这些类。这个 scope仅在编译和测试类路径上可用,并且是 不是过渡性的。
- 运行时此范围表示依赖项是 不需要编译,但是用于执行。它在 运行时和测试类路径,但不是编译类路径。
- 测试这个 scope表示正常使用时不需要依赖项 应用程序,仅适用于测试编译和 执行阶段。
- 系统此范围与提供的类似,但不包括 你必须提供明确包含它的JAR。神器 始终可用,不会在存储库中查找。
- 导入(仅限 在Maven 2.0.9或更高版本中可用)此范围仅用于 pom类型的依赖关系。它 表示应该用。替换指定的POM POM部分中的依赖关系。自从他们 被替换,实际上并不具有导入范围的依赖项 参与限制依赖的传递性。
因此,在Maven项目中,开发人员会指出应该在应用程序中捆绑哪些依赖项,哪些不应该捆绑。
基本上有两种情况:
如果您正在构建Web应用程序(WAR或EAR格式)并想要部署它,或者如果您正在构建一个实际的可运行jar,那么您将需要将其与所有依赖项一起捆绑在一起compile
和runtime
。
如果您正在构建一个库,那么就不会对您的库打包任何依赖。而是包含pom.xml
,以便其他人知道您的库需要什么依赖。要让Maven知道如何为给定的jar找到关联的POM,最好和最常见的解决方案是将库部署到Maven存储库。 Repos有一个目录结构,可以帮助Maven找到正确的库版本,并找到指示所需依赖关系的POM。
根据您的库是否是开源的,您可以通过某些存储库(如Sonatype(complete list here)免费托管。但您也可以通过安装Nexus等专用软件或将Github项目配置为repo as is explained on this blog来设置自己的存储库。