Extend the external artifact storage feature

Artifacts are the physical files that make up a specific version of an application. For example, an application binary, configuration files, or web content. When adding an artifact to a deployment package, you can either:

  • Upload an artifact that will be stored in the Deploy internal repository, or
  • Specify the uniform resource identifier (URI) of an externally stored artifact, which Deploy will resolve when it needs to access the file. For more information, see Add an externally stored artifact to a package.

By default, Deploy supports externally stored artifacts in Maven repositories, including Artifactory and Nexus, and HTTP/HTTPS locations. You can also implement support for any store that can be accessed with Java.

For example, a service called “Acme Cloud” that can store artifacts uses the following schema to identify artifacts:


In this example, Acme Cloud provides acme-cloud library to access data in its storage.

Step 1 Implement an ArtifactResolver interface

An ArtifactResolver interface instructs Deploy to retrieve artifacts using URIs with the acme protocol. A single resolver can support multiple protocols.

For more information, see the ArtifactResolver documentation.

    import com.xebialabs.deployit.engine.spi.artifact.resolution.ArtifactResolver;
    import com.xebialabs.deployit.engine.spi.artifact.resolution.ArtifactResolver.Resolver;
    import com.xebialabs.deployit.engine.spi.artifact.resolution.ResolvedArtifactFile;
    import com.xebialabs.deployit.plugin.api.udm.artifact.SourceArtifact;

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URI;
    import java.net.URISyntaxException;

    import com.acme.cloud.AcmeCloudClient;
    import com.acme.cloud.AcmeCloudFile;

    @Resolver(protocols = {"acme"})
    public class AcmeCloudArtifactResolver implements ArtifactResolver {

      public ResolvedArtifactFile resolveLocation(SourceArtifact artifact) {

        AcmeCloudClient acmeCloudClient = new AcmeCloudClient();
        AcmeCloudFile acmeCloudFile = acmeCloudClient.fetch(artifact.getFileUri());

        return new ResolvedArtifactFile() {
          public String getFileName() {
            return acmeCloudFile.getFilename();

          public InputStream openStream() throws IOException {
            return acmeCloudFile.getInputStream();

          public void close() throws IOException {

      public boolean validateCorrectness(SourceArtifact artifact) {
        try {
          return new URI(artifact.getFileUri()).getScheme().equals("acme");
          } catch (URISyntaxException e) {
            return false;

Important: You must put the @Resolver annotation on your class. This indicates that the resolver must be picked up and registered. The protocol name must be compatible with the URI specification. It can not contain the dash (-) character.

Step 2 Add the resolver to the Deploy classpath

To make Deploy aware of the resolver, you must compile the class and put it on the classpath of the server, along with third-party libraries. You must then restart the server.

Step 3 Specify fileUri in udm.SourceArtifact

When you create a deployable configuration item (CI) of any type that extends udm.SourceArtifact, you can specify the fileUri property using the protocol described in your resolver.

After adding the AcmeCloudArtifactResolver resolver, you can create an artifact pointing to acme:cloud42/artifact.jar, and Deploy can deploy it.