# Codehaus Cargo : JSR88

Created by Former user, last modified by S. Ali Tokmen on Aug 26, 2023

### Definition

JSR88-compliant containers support

### Explanation

Cargo supports JSR 88: J2EE Application Deployment API, allowing it to be used with any JSR88-compliant container.

The core functionality is implemented by the `o.c.c.container.spi.deployer.AbstractJsr88Deployer` class (a Deployer implementation), which acts as a proxy to the JSR88 `DeploymentManager`.

### GlassFish 6.x onwards, as well as newer versions of Payara

The GlassFish 6.x container doesn't have any remote deployers yet, as GlassFish 6.0 lacks JSR-88 support and it is unclear whether this will be included in a future release. Until then, please follow the remote deployment instructions for GlassFish 6.x.

Recent versions of Payara might have issues getting deployables uploaded via JSR-88, resulting in errors such as:

    Distributing failed: Action failed Deploying application to target server failed; File not found

If you encounter such errors, please follow the remote deployment instructions for recent Payara versions.

### GlassFish 3.x to 5.x and Payara

The GlassFish 3.x, GlassFish 4.x, GlassFish 5.x and Payara remote containers use the JSR-88 API. For the connection to succeed, the following JARs need to be in the container classpath or in the current Java Thread's context classloader:

- deployment-client.jar and its dependencies - for GlassFish 3.x, these seem to be:
  - admin-cli.jar
  - auto-depends.jar
  - common-util.jar
  - glassfish-api.jar
  - deployment-common.jar
  - hk2-core.jar

Here is an example code for the users of the Java API:

    List<URL> urls = new ArrayList<URL>();

    // Add many libraries from GlassFish
    for (File jar : new File(this.localContainer.getHome(), "glassfish/modules").listFiles())
    {
        if (jar.isFile())
        {
            urls.add(jar.toURI().toURL());
        }
    }

    // Create a ClassLoader contaning all these JARs
    URL[] urlsArray = new URL[urls.size()];
    urlsArray = urls.toArray(urlsArray);
    URLClassLoader classLoader = new URLClassLoader(urlsArray, Thread.currentThread().getContextClassLoader());
    Thread.currentThread().setContextClassLoader(classLoader);

    // Now, create the GlassFish Remote container
    ...

Here is an example Maven 3 plugin configuration:

    <plugin>
      <groupId>org.codehaus.cargo</groupId>
      <artifactId>cargo-maven3-plugin</artifactId>
      <version>${cargo.plugin.version}</version>
      <configuration>
        <container>
          <containerId>glassfish3x</containerId>
          <type>remote</type>
        </container>
        <configuration>
          <type>runtime</type>
          <properties>
            <cargo.hostname>virtualbox-xp</cargo.hostname>
            <cargo.rmi.port>4848</cargo.rmi.port>
          </properties>
        </configuration>
      </configuration>
      <dependencies>
        <dependency>
          <groupId>org.glassfish.deployment</groupId>
          <artifactId>deployment-client</artifactId>
          <version>3.0.1</version>
        </dependency>
      </dependencies>
    </plugin>

When adding the `org.glassfish.deployment:deployment-client` dependency, please make sure that the version matches exactly the targeted GlassFish server's version (beware the updates that you install on GlassFish, these indeed change the version of your server); else you might run into unexpected surprises like:

    error submitting remote command: com.sun.enterprise.admin.cli.CommandException:
       CLI001 Invalid Command: list: InvalidCommandException -> [Help 1]

or

    GlassFish list help command report

    Exit Code : SUCCESS
    list - null

    monitor
    GeneratedHelp true
    pattern_operand
    SYNOPSIS Usage: list [--monitor=false] pattern %%%EOL%%%

The list of versions you can choose from can be found on:

- https://repo.maven.apache.org/maven2/org/glassfish/deployment/deployment-client/ for GlassFish version 3.1.1,
- https://repo.maven.apache.org/maven2/org/glassfish/main/deployment/deployment-client/ for GlassFish 3.1.2 onwards and earlier versions of Payara,
- https://repo.maven.apache.org/maven2/fish/payara/extras/payara-embedded-web/ (which unfortunately happens to be quite a large JAR file) for later versions of Payara.

When you configure the GlassFish or Payara server to only use modern versions of TLS (and hence block older TLS versions), you might get an error message such as the below:

    error submitting remote command: org.glassfish.api.admin.CommandException:
       javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake: SSL peer shut down incorrectly

That happens because unfortunately even the latest version of the GlassFish Deployment Client dependency uses TLS version 1, and offers to ways to change it.

Later versions of the Payara deployment client fix this issue by setting the default to a modern TLS version:

- You can reference the proper version of the following (unfortunately, very large) artifact: https://repo.maven.apache.org/maven2/fish/payara/extras/payara-embedded-web/
- These newer versions also support a `fish.payara.clientHttpsProtocol` system variable you can set on the Java VM, enabling the choice between different TLS versions if needed