I currently write a Java program that deploys a lot of legacy jars to Nexus. My approach is to invoke a process that starts the deploy:deploy-file
goal on the command line
mvn deploy:deploy-file ...
This is quite slow. I wonder if there is a faster way to do this?
If you specifically target Nexus, you might find simpler to use their REST API to perform the upload:
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 [email protected] -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 [email protected] -F [email protected] -u admin:admin123 http://localhost:8081/nexus/service/local/artifact/maven/content
In a Java program, you can then use HttpURLConnection
to make that POST call (example of that here with authentication here and documentation of cURL here). Basically, in the POST parameters, you need to have r=releases
, hasPom=true
(or false
if you're uploading a POM with it), e
for the extension of the artifact, g
, a
, v
and p
for the coordinates (groupId, artifactId, version and packaging) and finally file
for the file to deploy.
Note that you won't be able to upload snapshots because it is explicitely disabled.
If you want a more generic solution, that would work for whatever artifact, and for whatever remote repository (even a local one), you can directly use the Aether API, which is used under the scenes by Maven 3.1 and higher. The team has an example of such a task in the DeployArtifacts
sample.
Add to your project the Aether dependencies:
<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>
And then you can have the following code to deploy artifacts:
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;
}
This code will deploy a single artifact having the given coordinates (groupId, artifactId, type, classifier and version) to the configured remote repository:
""
as the classifier.setFile
on the Artifact
."default"
layout is the one used by Maven 2 repository (in contrast to the "legacy"
layout for Maven 1). The URL is the same one as you would use inside the deploy-file
goal, so file:///C:/m2-repo
or scp://host.com/path/to/repo
.Authentication
to connect to the remote repository (as shown in the snippet).If you wish to deploy attached artifacts with it, like a POM file, you can create a SubArtifact
with:
Artifact pomArtifact = new SubArtifact(artifact, "", "pom");
pomArtifact = pomArtifact.setFile(new File("pom.xml"));
This would attach a POM artifact, without classifier, to the artifact configured above. Then you can add it to the deploy request like the main one:
deployRequest.addArtifact(artifact).addArtifact(pomArtifact);
and the both of them will be deployed.
You can do it programmatically in Java with the Eclipse Aether API. Check out the source of my Maven Repository Tools for more detail. In fact you might be able to use it straight out of the box for your needs if all your artifacts are already in a local folder in Maven repository format.
Specifically the deployment related code is in
https://github.com/simpligility/maven-repository-tools/blob/master/maven-repository-provisioner/src/main/java/com/simpligility/maven/provisioner/MavenRepositoryDeployer.java
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With