以编程方式将工件部署到 Nexus 的快速方法(在 Java 中)
Quick way to programmatically deploy artifacts to Nexus (in Java)
我目前正在编写一个 Java 程序,用于将大量遗留 jar 部署到 Nexus。我的方法是在命令行
上调用启动 deploy:deploy-file
目标的进程
mvn deploy:deploy-file ...
这很慢。我想知道是否有更快的方法来做到这一点?
如果您专门针对 Nexus,您可能会发现使用 their REST API 执行上传更简单:
Here are some examples using curl.
Uploading an artifact and generating a pom file:
curl -v -F r=releases -F hasPom=false -F e=jar -F g=com.test -F a=project -F v=1.0 -F p=jar -F file=@project-1.0.jar -u admin:admin123 http://localhost:8081/nexus/service/local/artifact/maven/content
Uploading an artifact with a pom file:
curl -v -F r=releases -F hasPom=true -F e=jar -F file=@pom.xml -F file=@project-1.0.jar -u admin:admin123 http://localhost:8081/nexus/service/local/artifact/maven/content
在 Java 程序中,您可以使用 HttpURLConnection
进行 POST 调用 (example of that here with authentication here and documentation of cURL here)。基本上,在 POST 参数中,你需要有 r=releases
、hasPom=true
(或者 false
,如果你用它上传 POM),e
工件的扩展,g
、a
、v
和 p
用于坐标(groupId、artifactId、版本和包装),最后 file
用于要部署的文件。
请注意,您将无法上传快照 because it is explicitely disabled。
如果你想要一个更通用的解决方案,它适用于任何工件,也适用于任何远程存储库(甚至是本地存储库),你可以直接使用在场景下使用的 Aether API通过 Maven 3.1 及更高版本。该团队在 DeployArtifacts
示例中有此类任务的示例。
将 Aether 依赖项添加到您的项目中:
<dependencies>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-impl</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-file</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-http</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<version>${mavenVersion}</version>
</dependency>
</dependencies>
<properties>
<aetherVersion>1.1.0</aetherVersion>
<mavenVersion>3.3.9</mavenVersion>
</properties>
然后您可以使用以下代码来部署工件:
public static void main(String[] args) throws DeploymentException {
RepositorySystem system = newRepositorySystem();
RepositorySystemSession session = newSession(system);
Artifact artifact = new DefaultArtifact("groupId", "artifactId", "classifier", "extension", "version");
artifact = artifact.setFile(new File("/path/to/file"));
// add authentication to connect to remove repository
Authentication authentication = new AuthenticationBuilder().addUsername("username").addPassword("password").build();
// creates a remote repo at the given URL to deploy to
RemoteRepository distRepo = new RemoteRepository.Builder("id", "default", "url").setAuthentication(authentication).build();
DeployRequest deployRequest = new DeployRequest();
deployRequest.addArtifact(artifact);
deployRequest.setRepository(distRepo);
system.deploy(session, deployRequest);
}
private static RepositorySystem newRepositorySystem() {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
return locator.getService(RepositorySystem.class);
}
private static RepositorySystemSession newSession(RepositorySystem system) {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository("target/local-repo");
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
return session;
}
此代码会将具有给定坐标(groupId、artifactId、类型、分类器和版本)的单个工件部署到配置的远程存储库:
- 在坐标中,可以传一个空String留空。例如,要在没有分类器的情况下进行部署,您可以使用
""
作为分类器。
- 要部署的文件是使用
Artifact
上的方法 setFile
设置的。
- 远程存储库配置了它的 ID、布局和 URL。
"default"
布局是 Maven 2 存储库使用的布局(与 "legacy"
layout for Maven 1). The URL is the same one as you would use inside the deploy-file
goal 相反,因此 file:///C:/m2-repo
或 scp://host.com/path/to/repo
.
- 如有必要,您可以创建一个
Authentication
以连接到远程存储库(如代码片段所示)。
如果你想用它部署附加的工件,比如 POM 文件,你可以创建一个 SubArtifact
用:
Artifact pomArtifact = new SubArtifact(artifact, "", "pom");
pomArtifact = pomArtifact.setFile(new File("pom.xml"));
这会将一个没有分类器的 POM 工件附加到上面配置的工件。然后你可以像主要的那样将它添加到部署请求中:
deployRequest.addArtifact(artifact).addArtifact(pomArtifact);
并且他们两个都将被部署。
您可以在 Java 中使用 Eclipse Aether API 以编程方式完成此操作。查看我的 Maven Repository Tools 的来源以获取更多详细信息。事实上,如果您的所有工件都已经以 Maven 存储库格式位于本地文件夹中,那么您可以直接使用它来满足您的需要。
具体部署相关代码在
我目前正在编写一个 Java 程序,用于将大量遗留 jar 部署到 Nexus。我的方法是在命令行
上调用启动deploy:deploy-file
目标的进程
mvn deploy:deploy-file ...
这很慢。我想知道是否有更快的方法来做到这一点?
如果您专门针对 Nexus,您可能会发现使用 their REST API 执行上传更简单:
Here are some examples using curl.
Uploading an artifact and generating a pom file:
curl -v -F r=releases -F hasPom=false -F e=jar -F g=com.test -F a=project -F v=1.0 -F p=jar -F file=@project-1.0.jar -u admin:admin123 http://localhost:8081/nexus/service/local/artifact/maven/content
Uploading an artifact with a pom file:
curl -v -F r=releases -F hasPom=true -F e=jar -F file=@pom.xml -F file=@project-1.0.jar -u admin:admin123 http://localhost:8081/nexus/service/local/artifact/maven/content
在 Java 程序中,您可以使用 HttpURLConnection
进行 POST 调用 (example of that here with authentication here and documentation of cURL here)。基本上,在 POST 参数中,你需要有 r=releases
、hasPom=true
(或者 false
,如果你用它上传 POM),e
工件的扩展,g
、a
、v
和 p
用于坐标(groupId、artifactId、版本和包装),最后 file
用于要部署的文件。
请注意,您将无法上传快照 because it is explicitely disabled。
如果你想要一个更通用的解决方案,它适用于任何工件,也适用于任何远程存储库(甚至是本地存储库),你可以直接使用在场景下使用的 Aether API通过 Maven 3.1 及更高版本。该团队在 DeployArtifacts
示例中有此类任务的示例。
将 Aether 依赖项添加到您的项目中:
<dependencies>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-impl</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-file</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-http</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<version>${mavenVersion}</version>
</dependency>
</dependencies>
<properties>
<aetherVersion>1.1.0</aetherVersion>
<mavenVersion>3.3.9</mavenVersion>
</properties>
然后您可以使用以下代码来部署工件:
public static void main(String[] args) throws DeploymentException {
RepositorySystem system = newRepositorySystem();
RepositorySystemSession session = newSession(system);
Artifact artifact = new DefaultArtifact("groupId", "artifactId", "classifier", "extension", "version");
artifact = artifact.setFile(new File("/path/to/file"));
// add authentication to connect to remove repository
Authentication authentication = new AuthenticationBuilder().addUsername("username").addPassword("password").build();
// creates a remote repo at the given URL to deploy to
RemoteRepository distRepo = new RemoteRepository.Builder("id", "default", "url").setAuthentication(authentication).build();
DeployRequest deployRequest = new DeployRequest();
deployRequest.addArtifact(artifact);
deployRequest.setRepository(distRepo);
system.deploy(session, deployRequest);
}
private static RepositorySystem newRepositorySystem() {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
return locator.getService(RepositorySystem.class);
}
private static RepositorySystemSession newSession(RepositorySystem system) {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository("target/local-repo");
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
return session;
}
此代码会将具有给定坐标(groupId、artifactId、类型、分类器和版本)的单个工件部署到配置的远程存储库:
- 在坐标中,可以传一个空String留空。例如,要在没有分类器的情况下进行部署,您可以使用
""
作为分类器。 - 要部署的文件是使用
Artifact
上的方法setFile
设置的。 - 远程存储库配置了它的 ID、布局和 URL。
"default"
布局是 Maven 2 存储库使用的布局(与"legacy"
layout for Maven 1). The URL is the same one as you would use inside thedeploy-file
goal 相反,因此file:///C:/m2-repo
或scp://host.com/path/to/repo
. - 如有必要,您可以创建一个
Authentication
以连接到远程存储库(如代码片段所示)。
如果你想用它部署附加的工件,比如 POM 文件,你可以创建一个 SubArtifact
用:
Artifact pomArtifact = new SubArtifact(artifact, "", "pom");
pomArtifact = pomArtifact.setFile(new File("pom.xml"));
这会将一个没有分类器的 POM 工件附加到上面配置的工件。然后你可以像主要的那样将它添加到部署请求中:
deployRequest.addArtifact(artifact).addArtifact(pomArtifact);
并且他们两个都将被部署。
您可以在 Java 中使用 Eclipse Aether API 以编程方式完成此操作。查看我的 Maven Repository Tools 的来源以获取更多详细信息。事实上,如果您的所有工件都已经以 Maven 存储库格式位于本地文件夹中,那么您可以直接使用它来满足您的需要。
具体部署相关代码在