├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── luooqi │ │ └── tools │ │ └── maven │ │ ├── DependenceHelper.java │ │ ├── DependenceInfo.java │ │ ├── Main.java │ │ └── StringBuilderOutputHandler.java └── resources │ └── logback.xml └── test └── java └── com └── luooqi └── tools └── maven └── DependenceHelperTest.java /README.md: -------------------------------------------------------------------------------- 1 | # maven-dependency-downloader 2 | 本项目实现了两种功能: 3 | 1. 根据pom.xml文件将其全部依赖下载到指定的文件夹; 4 | 2. 根据Jar信息(groupId:artifactId:version)将其全部依赖下载到指定的文件夹。 5 | 6 | > 需要注意的是环境变量必须配置:MAVEN_HOME 7 | 8 | ## 背景 9 | 从今年开始,内网很多项目开始使用 Maven 进行 Java 工程的 Jar 包管理,使用 Maven 自然比以前的 lib 文件夹要方便很多,其优点在这里就不罗列了,谁用谁知道。 10 | 11 | 但是在没有网络的情况下使用 Maven 还是一件很艰难的事情,还好可以在内网搭建一个 Maven 私服。但是想要把整个 Maven 仓库同步到内网也是不可能的,因此一般是需要开发的适合把其依赖项添加到 Maven 仓库。 12 | 13 | 例如我需要开发 Elasticsearch 工具包,需要用到 ES 相关的 Jar 包,我可以在外网新建一个项目,然后添加我的依赖项,最后将依赖打包到内网。 14 | 15 | 这里存在的问题就是,全量打包是很简单的,增量打包很困难,你可以`通过每次改变本地仓库地址来实现增量打包`。但是每次手动修改 Maven 的配置文件也是一件很繁琐的事情,那么是否有工具可以帮我们实现增量打包呢? 16 | 17 | 答案当然是有的,本文介绍的工具将解决增量打包的问题: 18 | 1. 根据 pom.xml 文件将其全部依赖下载到指定的文件夹; 19 | 2. 根据 Jar 信息(`groupId:artifactId:version`)将其全部依赖下载到指定的文件夹。 20 | 21 | ## 根据 pom 文件获取其全部依赖 22 | ### Apache Maven Invoker 23 | 先看一下官方对该 API 的描述:在很多情况下,我们为了避免对系统的 Maven 环境造成污染,亦或是我们想使用用户目录作为 Maven 的工作目录进行项目构建,总之,`我们希望在一个全新的环境中启动 Maven 构建`。我们可以使用此 API 触发 Maven 构建,此 API 可以执行用户提供的命令行,可以捕获命令行运行中的错误信息,同时支持用户自定义输出(InvocationOutputHandler)和输入(InputStream)类。 24 | 25 | 翻译的效果很差,举个例子:我想根据pom.xml文件获取该文件的全部依赖,借助 Maven 工具,我们只需要在 pom.xml 所在文件夹下使用命令行执行`mvn dependency:tree`即可获取其全部依赖。 26 | 27 | 现在如果我们想通过程序的方式来实现,借助`Apache Maven Invoker`即可,下面代码展示了如何根据 pom.xml 获取其全部依赖: 28 | ``` 29 | /** 30 | * 根据POM文件获取全部依赖信息 31 | * @param pomFilePath POM文件路径 32 | * @return 全部依赖信息 33 | * @throws FileNotFoundException MAVEN_HOME或者POM文件不存在 34 | */ 35 | public static List getDependenceListByPom(String pomFilePath) throws FileNotFoundException 36 | { 37 | InvocationRequest request = new DefaultInvocationRequest(); 38 | File file = new File(pomFilePath); 39 | if (!file.exists()) 40 | { 41 | throw new FileNotFoundException("pom文件路径有误:" + pomFilePath); 42 | } 43 | request.setPomFile(file); 44 | request.setGoals(Collections.singletonList("dependency:tree")); 45 | String output = getInvokeOutput(request); 46 | if (StrUtil.isBlank(output)) 47 | { 48 | return null; 49 | } 50 | Matcher matcher = depPattern.matcher(output); 51 | List result = new ArrayList(); 52 | while (matcher.find()) 53 | { 54 | DependenceInfo dependenceInfo = new DependenceInfo(matcher.group(1),matcher.group(2),matcher.group(3),matcher.group(4)); 55 | result.add(dependenceInfo); 56 | } 57 | return result; 58 | } 59 | 60 | /** 61 | * 根据请求获取最终的控制台输出文本信息 62 | * @param request 请求 63 | * @return 控制台输出文本 64 | */ 65 | private static String getInvokeOutput(InvocationRequest request) throws FileNotFoundException 66 | { 67 | Invoker invoker = new DefaultInvoker(); 68 | String mavenHome = getMavenHome(); 69 | if (StrUtil.isBlank(mavenHome)) 70 | { 71 | throw new FileNotFoundException("未检测到MAVEN_HOME,请在环境变量中进行配置。"); 72 | } 73 | invoker.setMavenHome(new File(mavenHome)); 74 | StringBuilderOutputHandler outputHandler = new StringBuilderOutputHandler(); 75 | invoker.setOutputHandler(outputHandler); 76 | try 77 | { 78 | InvocationResult result = invoker.execute(request); 79 | if (result.getExitCode() != 0) 80 | { 81 | StaticLog.error("Build failed.-------------->"); 82 | StaticLog.error(outputHandler.getOutput()); 83 | return null; 84 | } 85 | return outputHandler.getOutput(); 86 | } 87 | catch (Exception ex) 88 | { 89 | StaticLog.error(ex); 90 | } 91 | return null; 92 | } 93 | ``` 94 | 95 | 可以看到代码新建了一个`dependency:tree`的请求,然后在环境变量找到`MAVEN_HOME`,命令执行后通过自定义的输出类(`StringBuilderOutputHandler`)获取控制台文本内容: 96 | ``` 97 | import org.apache.maven.shared.invoker.InvocationOutputHandler; 98 | 99 | public class StringBuilderOutputHandler implements InvocationOutputHandler 100 | { 101 | private StringBuilder output = new StringBuilder(); 102 | 103 | public void consumeLine(String s) 104 | { 105 | output.append(s).append("\r\n"); 106 | } 107 | 108 | public String getOutput() 109 | { 110 | return output.toString(); 111 | } 112 | } 113 | ``` 114 | 115 | 通过上述代码便可获取 pom 文件的全部外部依赖,接下来根据依赖信息把依赖文件下载下来即可。 116 | 117 | ### 下载依赖文件 118 | 下载依赖文件有两种方法: 119 | 1. 自行根据依赖信息从 Maven 仓库下载依赖项的 jar 和 pom.xml 文件,然后建立本地路径,将下载的文件放在相应的位置即可; 120 | 2. 借助工具帮助我们下载。 121 | 122 | 借助工具下载,有两种方法: 123 | 1. 之前谷歌到的一种方法,使用`org.eclipse.aether`的一系列工具包,可以实现只需要提供 Jar 包信息即可完成全部依赖下载; 124 | 2. 写文章到此刻,我觉得上述获取`dependency:tree`的方式应该也可以下载依赖。 125 | 126 | #### 使用 org.eclipse.aether 工具包下载全部依赖 127 | 第一种方法整体流程就是设置一下自定义的 Maven 中央仓库地址,然后设置一下本地自定义的仓库目录,设置一下网络代理,最后调用 API 就会自动下载依赖,代码如下: 128 | ``` 129 | /** 130 | * 根据Artifact信息下载其相关依赖,并存储到指定的文件夹 131 | * @param artifactStr Artifact信息,例如:org.apache.maven.shared:maven-invoker:3.0.1 132 | * @param storePath 存储的路径 133 | * @param theScope Scope 134 | * @return 全部依赖信息 135 | */ 136 | public static List downloadDependency(String artifactStr, String storePath, String theScope) 137 | { 138 | DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); 139 | RepositorySystem system = newRepositorySystem(locator); 140 | RepositorySystemSession session = newSession(system, storePath); 141 | 142 | Artifact artifact = new DefaultArtifact(artifactStr); 143 | DependencyFilter theDependencyFilter = DependencyFilterUtils.classpathFilter(theScope); 144 | 145 | RemoteRepository central = new RemoteRepository.Builder("central", "default", "http://central.maven.org/maven2/").build(); 146 | CollectRequest theCollectRequest = new CollectRequest(); 147 | theCollectRequest.setRoot(new org.eclipse.aether.graph.Dependency(artifact, theScope)); 148 | theCollectRequest.addRepository(central); 149 | 150 | DependencyRequest theDependencyRequest = new DependencyRequest(theCollectRequest, theDependencyFilter); 151 | List resultList = new ArrayList(); 152 | try 153 | { 154 | DependencyResult theDependencyResult = system.resolveDependencies(session, theDependencyRequest); 155 | for (ArtifactResult theArtifactResult : theDependencyResult.getArtifactResults()) { 156 | Artifact theResolved = theArtifactResult.getArtifact(); 157 | DependenceInfo depInfo = new DependenceInfo(theResolved.getGroupId(), theResolved.getArtifactId(), theResolved.getVersion(), JavaScopes.COMPILE); 158 | resultList.add(depInfo); 159 | } 160 | } 161 | catch (Exception e) 162 | { 163 | e.printStackTrace(); 164 | } 165 | return resultList; 166 | } 167 | 168 | private static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) { 169 | locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); 170 | locator.addService(TransporterFactory.class, FileTransporterFactory.class); 171 | locator.addService(TransporterFactory.class, HttpTransporterFactory.class); 172 | return locator.getService(RepositorySystem.class); 173 | } 174 | 175 | private static RepositorySystemSession newSession(RepositorySystem system, String storePath) { 176 | DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); 177 | LocalRepository localRepo = new LocalRepository(storePath); 178 | session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); 179 | return session; 180 | } 181 | ``` 182 | 本方法的确可以下载到全部依赖,但是有一个缺点就是会将一些可选的依赖下载下来,如下如所示: 183 | 184 | ![可选的依赖会被下载](http://img.luooqi.com/FjanwBuEfm1bta1eVo6UKWmRiN-w) 185 | 186 | #### 使用 Maven Invoker 下载全部依赖 187 | 这个方法是写文章的时候进行验证的,效果很不错,代码简洁高效,是根据 pom 文件下载全部依赖的最佳方案。 188 | 189 | 其原理和上面的执行`dependency:tree`是一致的,在 Maven 官网查询到使用`dependency:resolve`可以下载到全部依赖到本地文件。那么现在只需要有个地方可以自定义本地仓库即可,幸运的是`Maven Invoker`支持自定义本地仓库: 190 | ``` 191 | Invoker invoker = new DefaultInvoker(); 192 | String mavenHome = getMavenHome(); 193 | if (StrUtil.isNotBlank(localRepo)) 194 | { 195 | //在此设置本地仓库 196 | invoker.setLocalRepositoryDirectory(new File(localRepo)); 197 | } 198 | invoker.setMavenHome(new File(mavenHome)); 199 | ``` 200 | 201 | ## 总结 202 | 如果根据 pom 文件下载依赖则推荐使用`Maven Invoker`方案;如果需要通过 Artifact 信息(`groupId:artifactId:version`)下载依赖则推荐使用`org.eclipse.aether`工具包;详细使用可以参考测试代码。 203 | 204 | > 完整代码地址:https://github.com/AnyListen/maven-dependency-downloader 205 | 206 | --- 207 | `追求高效、有节奏的研发过程; 打造高质量、创新的研发产品。 专注技术、钟情产品!` 208 | 209 | 欢迎扫码关注『朗坤极客驿站』,遇见更优秀的自己。 210 | 211 | ![](http://img.luooqi.com/Ft0jWj-Q69B67I8DE9pIBMOa6Bl5) 212 | 213 | ## 参考 214 | - [maven-invoker](http://maven.apache.org/shared/maven-invoker/usage.html) 215 | - [Maven: get all dependencies programmatically 216 | ](https://stackoverflow.com/questions/40813062/maven-get-all-dependencies-programmatically) 217 | - [dependency:tree](https://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html) 218 | - [Find all direct dependencies of an artifact on Maven Central 219 | ](https://stackoverflow.com/questions/39638138/find-all-direct-dependencies-of-an-artifact-on-maven-central/39641359) 220 | - [List of dependency jar files in Maven 221 | ](https://stackoverflow.com/questions/278596/list-of-dependency-jar-files-in-maven) 222 | - [How to download Maven artifacts with Maven >=3.1 and Eclipse Aether](https://www.mirkosertic.de/blog/2015/12/how-to-download-maven-artifacts-with-maven-3-1-and-eclipse-aether/) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.luooqi 8 | maven-dependency-downloader 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 1.1.0 13 | 3.3.9 14 | 15 | 16 | 17 | 18 | org.eclipse.aether 19 | aether-impl 20 | ${aetherVersion} 21 | 22 | 23 | org.eclipse.aether 24 | aether-connector-basic 25 | ${aetherVersion} 26 | 27 | 28 | org.eclipse.aether 29 | aether-transport-file 30 | ${aetherVersion} 31 | 32 | 33 | org.eclipse.aether 34 | aether-transport-http 35 | ${aetherVersion} 36 | 37 | 38 | org.apache.maven 39 | maven-aether-provider 40 | ${mavenVersion} 41 | 42 | 43 | 44 | org.apache.maven.shared 45 | maven-invoker 46 | 3.0.1 47 | 48 | 49 | 50 | 51 | cn.hutool 52 | hutool-all 53 | 4.1.17 54 | 55 | 56 | 57 | junit 58 | junit 59 | 4.12 60 | test 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | org.apache.maven.plugins 69 | maven-compiler-plugin 70 | 2.3.2 71 | 72 | 1.7 73 | 1.7 74 | UTF-8 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | maven-assembly-plugin 84 | 85 | false 86 | 87 | jar-with-dependencies 88 | 89 | 90 | 91 | com.luooqi.tools.maven.Main 92 | 93 | 94 | 95 | 96 | 97 | make-assembly 98 | package 99 | 100 | assembly 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/java/com/luooqi/tools/maven/DependenceHelper.java: -------------------------------------------------------------------------------- 1 | package com.luooqi.tools.maven; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.log.StaticLog; 5 | import org.apache.maven.repository.internal.MavenRepositorySystemUtils; 6 | import org.apache.maven.shared.invoker.*; 7 | import org.eclipse.aether.DefaultRepositorySystemSession; 8 | import org.eclipse.aether.RepositorySystem; 9 | import org.eclipse.aether.RepositorySystemSession; 10 | import org.eclipse.aether.artifact.Artifact; 11 | import org.eclipse.aether.artifact.DefaultArtifact; 12 | import org.eclipse.aether.collection.CollectRequest; 13 | import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; 14 | import org.eclipse.aether.graph.DependencyFilter; 15 | import org.eclipse.aether.impl.DefaultServiceLocator; 16 | import org.eclipse.aether.repository.LocalRepository; 17 | import org.eclipse.aether.repository.RemoteRepository; 18 | import org.eclipse.aether.resolution.*; 19 | import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; 20 | import org.eclipse.aether.spi.connector.transport.TransporterFactory; 21 | import org.eclipse.aether.transport.file.FileTransporterFactory; 22 | import org.eclipse.aether.transport.http.HttpTransporterFactory; 23 | import org.eclipse.aether.util.artifact.JavaScopes; 24 | import org.eclipse.aether.util.filter.DependencyFilterUtils; 25 | 26 | import java.io.File; 27 | import java.io.FileNotFoundException; 28 | import java.util.*; 29 | import java.util.regex.Matcher; 30 | import java.util.regex.Pattern; 31 | 32 | /** 33 | * maven-dependency-downloader 34 | * Created by 何志龙 on 2018-07-04. 35 | */ 36 | public class DependenceHelper 37 | { 38 | private static final Pattern depPattern = Pattern.compile("\\[INFO][^\\w]+([\\w.\\-]+):([\\w.\\-]+):jar:([\\w.\\-]+):([\\w.\\-]+)"); 39 | 40 | /** 41 | * 根据POM文件获取全部依赖信息 42 | * @param pomFilePath POM文件路径 43 | * @return 全部依赖信息 44 | * @throws FileNotFoundException MAVEN_HOME或者POM文件不存在 45 | */ 46 | public static List getDependenceListByPom(String pomFilePath) throws FileNotFoundException 47 | { 48 | InvocationRequest request = new DefaultInvocationRequest(); 49 | File file = new File(pomFilePath); 50 | if (!file.exists()) 51 | { 52 | throw new FileNotFoundException("pom文件路径有误:" + pomFilePath); 53 | } 54 | request.setPomFile(file); 55 | request.setGoals(Collections.singletonList("dependency:tree")); 56 | String output = getInvokeOutput(request, ""); 57 | if (StrUtil.isBlank(output)) 58 | { 59 | return null; 60 | } 61 | Matcher matcher = depPattern.matcher(output); 62 | List result = new ArrayList(); 63 | while (matcher.find()) 64 | { 65 | DependenceInfo dependenceInfo = new DependenceInfo(matcher.group(1),matcher.group(2),matcher.group(3),matcher.group(4)); 66 | result.add(dependenceInfo); 67 | } 68 | return result; 69 | } 70 | 71 | /** 72 | * 根据Artifact信息下载其相关依赖(默认Scope为COMPILE),并存储到指定的文件夹 73 | * @param artifactStr Artifact信息,例如:org.apache.maven.shared:maven-invoker:3.0.1 74 | * @param storePath 存储的路径 75 | * @return 全部依赖信息 76 | */ 77 | public static List downloadDependency(String artifactStr, String storePath) 78 | { 79 | return downloadDependency(artifactStr, storePath, JavaScopes.COMPILE); 80 | } 81 | 82 | /** 83 | * 根据Artifact信息下载其相关依赖,并存储到指定的文件夹 84 | * @param artifactStr Artifact信息,例如:org.apache.maven.shared:maven-invoker:3.0.1 85 | * @param storePath 存储的路径 86 | * @param theScope Scope 87 | * @return 全部依赖信息 88 | */ 89 | public static List downloadDependency(String artifactStr, String storePath, String theScope) 90 | { 91 | DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); 92 | RepositorySystem system = newRepositorySystem(locator); 93 | RepositorySystemSession session = newSession(system, storePath); 94 | 95 | Artifact artifact = new DefaultArtifact(artifactStr); 96 | DependencyFilter theDependencyFilter = DependencyFilterUtils.classpathFilter(theScope); 97 | 98 | //RemoteRepository central = new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build(); 99 | RemoteRepository central = new RemoteRepository.Builder("central", "default", "http://central.maven.org/maven2/").build(); 100 | CollectRequest theCollectRequest = new CollectRequest(); 101 | theCollectRequest.setRoot(new org.eclipse.aether.graph.Dependency(artifact, theScope)); 102 | //theCollectRequest.addRepository(central); 103 | theCollectRequest.addRepository(central); 104 | 105 | DependencyRequest theDependencyRequest = new DependencyRequest(theCollectRequest, theDependencyFilter); 106 | List resultList = new ArrayList(); 107 | try 108 | { 109 | DependencyResult theDependencyResult = system.resolveDependencies(session, theDependencyRequest); 110 | for (ArtifactResult theArtifactResult : theDependencyResult.getArtifactResults()) { 111 | Artifact theResolved = theArtifactResult.getArtifact(); 112 | DependenceInfo depInfo = new DependenceInfo(theResolved.getGroupId(), theResolved.getArtifactId(), theResolved.getVersion(), JavaScopes.COMPILE); 113 | resultList.add(depInfo); 114 | } 115 | } 116 | catch (Exception e) 117 | { 118 | e.printStackTrace(); 119 | } 120 | return resultList; 121 | } 122 | 123 | private static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) { 124 | locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); 125 | locator.addService(TransporterFactory.class, FileTransporterFactory.class); 126 | locator.addService(TransporterFactory.class, HttpTransporterFactory.class); 127 | return locator.getService(RepositorySystem.class); 128 | } 129 | 130 | private static RepositorySystemSession newSession(RepositorySystem system, String storePath) { 131 | DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); 132 | LocalRepository localRepo = new LocalRepository(storePath); 133 | session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); 134 | // set possible proxies and mirrorsD: 135 | //session.setProxySelector(new DefaultProxySelector().add(new Proxy(Proxy.TYPE_HTTP, "host", 3625), Arrays.asList("localhost", "127.0.0.1"))); 136 | //session.setMirrorSelector(new DefaultMirrorSelector().add("my-mirror", "http://mirror", "default", false, "external:*", null)); 137 | return session; 138 | } 139 | 140 | /** 141 | * 根据请求获取最终的控制台输出文本信息 142 | * @param request 请求 143 | * @return 控制台输出文本 144 | */ 145 | private static String getInvokeOutput(InvocationRequest request, String localRepo) throws FileNotFoundException 146 | { 147 | Invoker invoker = new DefaultInvoker(); 148 | String mavenHome = getMavenHome(); 149 | if (StrUtil.isBlank(mavenHome)) 150 | { 151 | throw new FileNotFoundException("未检测到MAVEN_HOME,请在环境变量中进行配置。"); 152 | } 153 | if (StrUtil.isNotBlank(localRepo)) 154 | { 155 | invoker.setLocalRepositoryDirectory(new File(localRepo)); 156 | } 157 | invoker.setMavenHome(new File(mavenHome)); 158 | StringBuilderOutputHandler outputHandler = new StringBuilderOutputHandler(); 159 | invoker.setOutputHandler(outputHandler); 160 | try 161 | { 162 | InvocationResult result = invoker.execute(request); 163 | if (result.getExitCode() != 0) 164 | { 165 | StaticLog.error("Build failed.-------------->"); 166 | StaticLog.error(outputHandler.getOutput()); 167 | return null; 168 | } 169 | return outputHandler.getOutput(); 170 | } 171 | catch (Exception ex) 172 | { 173 | StaticLog.error(ex); 174 | } 175 | return null; 176 | } 177 | 178 | /** 179 | * 获取Maven_Home 180 | */ 181 | private static String getMavenHome() 182 | { 183 | String[] arr = new String[]{"MAVEN_HOME", "MVN_HOME", "M2_HOME", "M3_HOME"}; 184 | String home; 185 | for (String str : arr) 186 | { 187 | home = System.getenv(str); 188 | if (!StrUtil.isBlank(home)) 189 | { 190 | return home; 191 | } 192 | } 193 | home = System.getenv("PATH"); 194 | if (!StrUtil.isBlank(home) && home.toLowerCase().contains("maven")) 195 | { 196 | String[] split = home.split("[:;]+"); 197 | for (String str : split) 198 | { 199 | if (str.toLowerCase().contains("maven")) 200 | { 201 | return str; 202 | } 203 | } 204 | } 205 | arr = new String[]{"maven.home", "mvn.home", "m2.home", "m3.home"}; 206 | for (String str : arr) 207 | { 208 | home = System.getProperty(str); 209 | if (!StrUtil.isBlank(home)) 210 | { 211 | return home; 212 | } 213 | } 214 | return null; 215 | } 216 | 217 | 218 | /** 219 | * 根据pom.xml下载全部依赖(默认作用于为COMPILE)到指定的路径 220 | * @param pomFilePath POM文件路径 221 | * @param repositoryPath 存储的路径 222 | * @throws FileNotFoundException MAVEN_HOME或者POM文件不存在 223 | */ 224 | public static void downloadDependenceWithPomFile(String pomFilePath, String repositoryPath) throws FileNotFoundException 225 | { 226 | downloadDependenceWithPomFile(pomFilePath, repositoryPath, JavaScopes.COMPILE); 227 | } 228 | 229 | /** 230 | * 根据pom.xml下载全部依赖到指定的路径 231 | * @param pomFilePath POM文件路径 232 | * @param repositoryPath 存储的路径 233 | * @param scope 作用域 234 | * @throws FileNotFoundException MAVEN_HOME或者POM文件不存在 235 | */ 236 | public static void downloadDependenceWithPomFile(String pomFilePath, String repositoryPath, String scope) throws FileNotFoundException 237 | { 238 | List depList = getDependenceListByPom(pomFilePath); 239 | if (depList == null) 240 | { 241 | StaticLog.info("未解析到任何依赖!"); 242 | return; 243 | } 244 | List resultList = new ArrayList(); 245 | System.out.println("开始下载:"); 246 | for (DependenceInfo dep:depList) 247 | { 248 | List list = downloadDependency(dep.toString(), repositoryPath, scope); 249 | if (list != null && list.size() > 0) 250 | { 251 | resultList.addAll(list); 252 | for(DependenceInfo dep1:list) 253 | { 254 | System.out.println("已下载:" + dep1); 255 | } 256 | } 257 | } 258 | StaticLog.info("----------------------------------------"); 259 | StaticLog.info("下载完成,总依赖个数:" + resultList.size()); 260 | } 261 | 262 | public static void downloadDeps(String pomFilePath, String repositoryPath) throws FileNotFoundException 263 | { 264 | InvocationRequest request = new DefaultInvocationRequest(); 265 | File file = new File(pomFilePath); 266 | if (!file.exists()) 267 | { 268 | throw new FileNotFoundException("pom文件路径有误:" + pomFilePath); 269 | } 270 | request.setPomFile(file); 271 | request.setGoals(Collections.singletonList("dependency:resolve")); 272 | 273 | //request.setBaseDirectory(new File(repositoryPath)); 274 | 275 | String output = getInvokeOutput(request, repositoryPath); 276 | if (StrUtil.isBlank(output)) 277 | { 278 | return; 279 | } 280 | System.out.println(output); 281 | Matcher matcher = depPattern.matcher(output); 282 | List result = new ArrayList(); 283 | while (matcher.find()) 284 | { 285 | DependenceInfo dependenceInfo = new DependenceInfo(matcher.group(1),matcher.group(2),matcher.group(3),matcher.group(4)); 286 | result.add(dependenceInfo); 287 | } 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/main/java/com/luooqi/tools/maven/DependenceInfo.java: -------------------------------------------------------------------------------- 1 | package com.luooqi.tools.maven; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | 5 | /** 6 | * maven-dependency-downloader 7 | * Created by 何志龙 on 2018-07-04. 8 | */ 9 | public class DependenceInfo 10 | { 11 | private String groupId; 12 | private String artifactId; 13 | private String version; 14 | private String scope; 15 | 16 | public DependenceInfo(){} 17 | 18 | public DependenceInfo(String groupId, String artifactId, String version, String scope) 19 | { 20 | this.groupId = groupId; 21 | this.artifactId = artifactId; 22 | this.version = version; 23 | this.scope = scope; 24 | } 25 | 26 | public String getGroupId() 27 | { 28 | return groupId; 29 | } 30 | 31 | public void setGroupId(String groupId) 32 | { 33 | this.groupId = groupId; 34 | } 35 | 36 | public String getArtifactId() 37 | { 38 | return artifactId; 39 | } 40 | 41 | public void setArtifactId(String artifactId) 42 | { 43 | this.artifactId = artifactId; 44 | } 45 | 46 | public String getVersion() 47 | { 48 | return version; 49 | } 50 | 51 | public void setVersion(String version) 52 | { 53 | this.version = version; 54 | } 55 | 56 | public String getScope() 57 | { 58 | return scope; 59 | } 60 | 61 | public void setScope(String scope) 62 | { 63 | this.scope = scope; 64 | } 65 | 66 | @Override 67 | public String toString() 68 | { 69 | return StrUtil.format("{}:{}:{}", this.getGroupId(), this.getArtifactId(), this.getVersion()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/luooqi/tools/maven/Main.java: -------------------------------------------------------------------------------- 1 | package com.luooqi.tools.maven; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.util.List; 5 | 6 | /** 7 | * maven-dependency-downloader 8 | * Created by 何志龙 on 2018-07-09. 9 | */ 10 | public class Main 11 | { 12 | public static void main(String[] args) throws FileNotFoundException 13 | { 14 | if (args.length < 2) 15 | { 16 | System.out.println("参数个数有误:\r\n 第一个参数:POM文件路径或者JAR信息 \r\n" + " 第二个参数:依赖存储路径 \r\n"); 17 | } 18 | String pomPath = args[0]; 19 | String respPath = args[1]; 20 | if (pomPath.toLowerCase().endsWith(".xml")) 21 | { 22 | DependenceHelper.downloadDependenceWithPomFile(pomPath, respPath); 23 | } 24 | else 25 | { 26 | List dependenceInfoList = DependenceHelper.downloadDependency(pomPath, respPath); 27 | System.out.println("已下载以下依赖:"); 28 | for (DependenceInfo dep:dependenceInfoList) 29 | { 30 | System.out.println(dep); 31 | } 32 | System.out.println("总依赖数:" + dependenceInfoList.size()); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/luooqi/tools/maven/StringBuilderOutputHandler.java: -------------------------------------------------------------------------------- 1 | package com.luooqi.tools.maven; 2 | 3 | import org.apache.maven.shared.invoker.InvocationOutputHandler; 4 | 5 | /** 6 | * maven-dependency-downloader 7 | * Created by 何志龙 on 2018-07-04. 8 | */ 9 | public class StringBuilderOutputHandler implements InvocationOutputHandler 10 | { 11 | private StringBuilder output = new StringBuilder(); 12 | 13 | public void consumeLine(String s) 14 | { 15 | output.append(s).append("\r\n"); 16 | } 17 | 18 | public String getOutput() 19 | { 20 | return output.toString(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${format} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/test/java/com/luooqi/tools/maven/DependenceHelperTest.java: -------------------------------------------------------------------------------- 1 | package com.luooqi.tools.maven; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.FileNotFoundException; 7 | import java.util.List; 8 | 9 | /** 10 | * maven-dependency-downloader 11 | * Created by 何志龙 on 2018-07-04. 12 | */ 13 | 14 | public class DependenceHelperTest 15 | { 16 | 17 | @Test 18 | public void getDependenceListByPom() throws FileNotFoundException 19 | { 20 | List list = DependenceHelper.getDependenceListByPom("D:\\Code\\Github\\maven-dependency-downloader.git\\trunk\\pom.xml"); 21 | System.out.println(list); 22 | } 23 | 24 | @Test 25 | public void getDependenceByInfo() throws FileNotFoundException 26 | { 27 | DependenceHelper.downloadDependenceWithPomFile("D:\\Code\\Github\\maven-dependency-downloader.git\\trunk\\pom.xml", "d:/my_test/"); 28 | } 29 | 30 | @Test 31 | public void downloadDependence() throws FileNotFoundException 32 | { 33 | DependenceHelper.downloadDeps("D:\\Code\\Github\\maven-dependency-downloader.git\\trunk\\pom.xml", "d:/resolve/"); 34 | } 35 | } 36 | --------------------------------------------------------------------------------