> For the complete documentation index, see [llms.txt](https://docs.licensespring.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.licensespring.com/sdks/java-sdk/java-modules/floating-client.md).

# Floating Client

Floating Client is a module that has everything related to floating licenses. See [**Floating Licenses**](/license-entitlements/floating-licenses.md) for more information about floating licenses.

To include Floating Client into your Maven/Gradle project add this snippet:

{% tabs %}
{% tab title="Maven" %}

```xml
     <dependencies>
       <dependency>
            <groupId>com.licensespring</groupId>
            <artifactId>licensespring-floating-client</artifactId>
            <version>2.16.1</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>jdk-java</id>
            <url>https://licensespring-maven.s3.eu-central-1.amazonaws.com/</url>
        </repository>
    </repositories>
```

{% endtab %}

{% tab title="Gradle" %}

```java
repositories {
    mavenLocal()
    maven {
        url = 'https://licensespring-maven.s3.eu-central-1.amazonaws.com/'
    }
}

dependencies {
    implementation 'com.licensespring:licensespring-floating-client:2.16.1'
}
```

{% endtab %}
{% endtabs %}

*Javadoc, Jar and OSGi bundle downloads can be found at:* [***Javadoc & Downloads***](/sdks/java-sdk/downloads-and-javadoc.md)

## Initializing the Floating Client module

The floating client, as opposed to License Client SDK, is implemented as a service. More than one instance can be created, and the usage template is you need one `FloatingLicenseService` per product that you need to use. For most use cases this is one. This approach enables having multiple products within your application and multiple licenses per `FloatingLicenseService` instance.

The `License` identity needs to be preserved somewhere within your application, as the references to active licenses are not saved within this module.

To initialize the SDK, you must supply authentication credentials and product information. You can choose one of two authentication methods:

{% stepper %}
{% step %}

## API Key Authentication

* **apiKey:** Your company API key
* **sharedKey:** A company-specific encryption key used when signing requests
  {% endstep %}

{% step %}

## OAuth Authorization

* **clientId:** Your client identifier
* **clientSecret:** Your client secret
  {% endstep %}
  {% endstepper %}

In addition to the authentication credentials, you must provide the **productCode**, an alphanumeric code identifying the specific product. The `apiKey` and `sharedKey` are available in the LicenseSpring Platform under "Settings -> Settings -> Keys." For [**OAuth Authorization**](/license-api/license-api-authorization/oauth-authorization.md), your `clientId` and `clientSecret` are available here: [**OAuth Configuration**](/vendor-platform/settings/oauth-configuration.md) . The `productCode` is defined when creating the product and ties the license to that specific product.

**Optional** Configuration parameters for initializing the Floating Client SDK:

* `addShutdownHook` indicates if you want the SDK to automatically release any currently active licenses on the device before you shut down the runtime process. Default is true.
* `enablePeriodicCheck` enables periodic calls to `checkLicense` method to prolong the license usage. It will be prolonged every time the license has passed half of its floating timeout time. Usage time is set through the LicenseSpring platform with the LicenseSpring platform with the `floatingTimeout` parameter in the product configuration.
* `checkSubscriber` subscriber on periodic check, default implementation is `DoNothingSubscriber`, but you can add your own implementation to handle the `onSuccess` and `onError` of the periodic check. This, of course, isn't a parameter you need to worry about if you chose not to enable periodic checks.
* `requestLogging` request logging for debug purposes, default is no request logging.
* `appName` name of the application using the SDK
* `appVersion` manually set the version of the application that's using the SDK.
* `identityProvider` set a custom `IdentityProvider` which generates unique keys for a particular device. Default implementation for floating is `ONCE_PER_PROCESS`. More details can be found on our [**Java Hardware (Device) IDs**](/sdks/java-sdk/java-hardware-device-ids.md) page.
* `cacheHardwareId` set to true to allow caching of hardware iDs. Default is true. You can change this to false if your hardware Id strategy isn't `ONCE_PER_PROCESS`.
* `enableNegativeConsumptions` enables the option to send negative consumptions, default is false.
* `proxyPort` and `proxyHost` used to setup a forward proxy, see more in [**Java Advanced Usage**](/sdks/java-sdk/java-advanced-usage.md)
* `requestTimeout` set the timeout of requests make to API (in seconds), default is 10 seconds
* `storeMachineInfo` false by default. This toggles the collection of additional machine data, which includes:
  * `hostname`
  * `ipAddress`
  * `macAddress`
  * `vmInfo`
  * `osInfo`
* `infoToStore` - specify what information to store, ignored if `storeMachineInfo` is false, defaults to ALL if left empty.

```java
// initialization with minimum parameters
try {
	FloatingConfiguration configuration = FloatingConfiguration.builder()
                .apiKey("api_key")
                .sharedKey("shared_key")
                .productCode("product_code")
                .build();
} catch (LicenseSpringConfigurationException e) {
    log.error(e.getCause().getMessage());
}

// OAuth minimum parameters
try {
	FloatingConfiguration configuration = FloatingConfiguration.builder()
                .clientId("client_id")
                .clientSecret("client_secret")
                .productCode("product_code")
                .build();
} catch (LicenseSpringConfigurationException e) {
    log.error(e.getCause().getMessage());
}
LicenseSpringConfiguration configuration = LicenseSpringConfiguration.builder()
                        
                        .sharedKey("shared-key")
                        .build();               

// initialization with more parameters
try {
	FloatingConfiguration configuration = FloatingConfiguration.builder()
                .apiKey("api-key")
                .productCode("product-code")
                .sharedKey("shared-key")
                .addShutdownHook(false)
                .requestLogging(Logger.Level.FULL)
                .appName("MyApplication")
                .appVersion("1.0.1")
                .enableNegativeConsumptions(true)
                .requestTimeout(60L)
                .storeMachineInfo(true)
                .infoToStore(InfoToStore.VM_INFO)
                .infoToStore(InfoToStore.HOSTNAME)
                .build();
} catch (LicenseSpringConfigurationException e) {
    log.error(e.getCause().getMessage());
}
```

## FloatingLicenseService

After setting up the SDK, there are a number of methods and objects available to the app developer.

To make the `FloatingLicenseService`, initialize it by passing the `FloatingConfiguration` object you set up earlier.

```java
FloatingLicenseService service = new FloatingLicenseService(configuration);
```

Now you can use the methods that `FloatingLicenseService` provides.

### activateLicense(ActivationLicense identity)

Attempts to activate the product using provided `ActivationLicense`. Returns the `LicenseData` object that has been activated. There are two available factory methods to make the `ActivationLicense` object, the method you need to use depends if your product is license key-based or user-based.

```java
// If your licenses are user based: (note that password is never saved in the sdk)
// ActivationLicense extends the LicenseIdentity class
ActivationLicense identity = ActivationLicense.fromUsername("username", "password");
// If your licenses are key based:
ActivationLicense identity = ActivationLicense.fromKey("license-key");

// Activate the license, the method returns LicenseData object
try {
	LicenseData data = service.activateLicense(identity);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}

// This is what LicenseData object looks like, so you can better grasp what fields of the object are at your disposal.
// All fields are read only.
public class LicenseData {
    String licenseSignature;
    LicenseType licenseType;
    boolean isTrial;

    List<LicenseFeature> productFeatures;
    List<CustomField> customFields;

    ZonedDateTime validityPeriod;
    ZonedDateTime maintenancePeriod;

    int totalConsumptions;
    int maxConsumptions;

    int maxActivations;
    int timesActivated;

    Customer customer;

    Product productDetails;

    boolean isFloatingCloud;
    int floatingUsers;
    boolean floatingInUse;
    int floatingTimeout;

    public boolean isExpired();
    public long daysRemaining();
}
```

### checkLicense(LicenseIdentity data)

After you activated the license you can now use the check method to prolong the usage of the license and check its validity, since it expires after floating timeout period has passed (this can be set up in product configuration on the LicenseSpring platform). This method returns `CheckResponse` object that contains `LicenseData`, `InstallationFile` and flags if license is active, enabled or expired.

This method can be called periodically if you leave the `enablePeriodicCheck` true in the `FloatingConfiguration` so you don't have to worry about the floating license expiring while the user is still using it.

```java
// You can use the previous identity to check the license
ActivationLicense identityFromUser = ActivationLicense.fromUsername("username", "password");
ActivationLicense identityFromKey = ActivationLicense.fromKey("license-key");

// or you can make a new LicenseIdentity object that doesn't contain the password
LicenseIdentity identityFromUser = LicenseIdentity.builder()
                .username("username")
                .build();

LicenseIdentity identityFromKey = LicenseIdentity.builder()
                .licenseKey("license-key")
                .build();

try {
	CheckResponse response = service.checkLicense(identityFromUser);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}

// CheckResponse object
public class CheckResponse {
    private transient LicenseData data;
    private transient InstallationFile file;

    private boolean licenseActive;
    private boolean licenseEnabled;
    private boolean isExpired;
}
```

### CheckLicenseSubscriber

The check subscriber can be added as a custom handler when the check API is called (e.g. in a background thread).

```java
public class MySubscriber implements CheckLicenseSubscriber{
    @Override
    public void onError(LicenseIdentity old, LicenseSpringException exception) {
        // handle the error
    }

    @Override
    public void onSuccess(CheckResponse checkResponse) {
        // the check response recieved
    }
}


// when building the configuration add the instance on the configuration builder

try {
	FloatingConfiguration configuration = FloatingConfiguration.builder()
                .apiKey("api-key")
                .productCode("product-code")
                .sharedKey("shared-key")
                .checkSubscriber(new MySubscriber())
                 .build();
} catch (LicenseSpringConfigurationException e) {
    log.error(e.getCause().getMessage());
}
```

### BorrowedLicenseExpirationSubscriber

The borrowed license expiration subscriber can be added as a custom handler when the borrowed license borrow time expires.

```java
public class MySubscriber implements BorrowedLicenseExpirationSubscriber{
    @Override
    public void onBorrowedLicenseExpiration(LicenseBorrowResponse response) {
        // Your custom handler
    }
}


// when building the configuration add the instance on the configuration builder

try {
	FloatingConfiguration configuration = FloatingConfiguration.builder()
                .apiKey("api-key")
                .productCode("product-code")
                .sharedKey("shared-key")
                .borrowedLicenseExpirationSubscriber(new MySubscriber())
                .build();
} catch (LicenseSpringConfigurationException e) {
    log.error(e.getCause().getMessage());
}
```

### addConsumption(LicenseIdentity identity, int consumptions)

If your license is the `Consumption` type you can increase the consumptions by the parameter provided. This method makes a request to the LicenseSpring server to increase the consumptions on the identity you provided.

```java
// see checkLicense method how you can build identity differently
LicenseIdentity identityFromKey = LicenseIdentity.builder()
                .licenseKey("license-key")
                .build();

// adds one consumption to the provided identity
try {
	service.addConsumption(identity, 1);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}

// if enableNegativeConsumptions is set to true in FloatingConfiguration object
// you can add negative consumptions
try {
	service.addConsumption(identity, -1);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### addFeatureConsumption(LicenseIdentity identity, int consumptions)

If your license is the `Consumption` type and you have certain features in your app that you want to track consumptions for separately, you can increase the consumptions of the feature by the parameter provided. This method makes a request to the LicenseSpring server to increase the feature consumptions on the identity you provided.

```java
// see checkLicense method how you can build identity differently
ActivationLicense identity = ActivationLicense.fromKey("license-key");

// adds one consumption on feature "feature" to the identity provided
try {
	service.addFeatureConsumption(identity, "feature", 1);	
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}

// if enableNegativeConsumptions is set to true in FloatingConfiguration object
// you can add negative feature consumptions
try {
	service.addConsumption(identity, "feature", -1);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
```

### installationFile(LicenseIdentity identity)

Returns the latest valid installation file, if installation files are defined in the LicenseSpring platform. For more details please see [**Product Versioning**](/product-configuration/product-versioning.md).

```java
// see checkLicense method how you can build identity differently
ActivationLicense identity = ActivationLicense.fromKey("license-key");

try {
	InstallationFile file = service.installationFile(identity);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### trackVariables(LicenseIdentity identity, Map\<String, String> variables)

Tracks device based variables for end uses.

```java
// see checkLicense method how you can build identity differently
ActivationLicense identity = ActivationLicense.fromKey("license-key");
// see checkLicense method how you can build identity differently
ActivationLicense identity = ActivationLicense.fromKey("license-key");

Map<String, String> variables = new HashMap<>();
variables.put("var1", "val1");
variables.put("var2", "val2");

try {
	service.trackVariables(identity, variables);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}

try {
	InstallationFile file = service.installationFile(identity);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### versions(LicenseIdentity identity)

Returns an array of strings with all available versions.

```java
// see checkLicense method for more ways to build identity
ActivationLicense identity = ActivationLicense.fromKey("license-key");

try {
	String[] versions = service.versions(LicenseIdentity.fromKey("license-key"));
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### productDetails()

Gets product details from LicenseSpring servers.

```java
try {
	Product product = service.productDetails();
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}

log.info(product.getProductName());
log.info(product.getShortCode());
log.info(product.isAllowTrial());
log.info(product.getTrialDays());
log.info(product.getAuthorizationMethod());

// product class
public class Product {
    private String productName;
    private String shortCode;
    private boolean allowTrial;
    private int trialDays;
    private String authorizationMethod;
}// see checkLicense method for more ways to build identity
ActivationLicense identity = ActivationLicense.fromKey("license-key");

try {
	String[] versions = service.versions(LicenseIdentity.fromKey("license-key"));
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### releaseLicense(LicenseIdentity identity)

A floating cloud license is released from a current device. You need to supply the license identity. This is done automatically before the process shuts down normally if you leave the `addShutdownHook` property true in the `FloatingConfiguration`. Additionally, the license is also deactivated for the current device.

```java
// see checkLicense method for more ways to build identity
ActivationLicense identity = ActivationLicense.fromKey("license-key");

try {
	service.releaseLicense(identity);
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### deactivateLicense(LicenseIdentity identity)

A license can be deactivated using this method, then the license can be used on another device. Returns true if deactivation was successful, false if it wasn't.

```java
// see checkLicense method for more ways to build identity
ActivationLicense identity = ActivationLicense.fromKey("license-key");

try {
	if (service.deactivateLicense(identity) {
        System.out.println("License successfully deactivated.");
    } else {
        System.out.println("Something went wrong.");
    }
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

### borrowLicense(LicenseIdentity identity)

A license can be borrowed using this method.

```java
// see checkLicense method for more ways to build identity
ActivationLicense identity = ActivationLicense.fromKey("license-key");
try {
  service.borrowLicense(identity, ZonedDateTime.now().plusHours(1));
} catch (LicenseSpringException e) {
    log.error(e.getCause().getMessage());
}
```

## changeOAuthClientSecret

Changes the OAuth Client Secret used for auth -> in case you have a rotating secret

```java
service.changeOAuthClientSecret("otherClientSecret");
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.licensespring.com/sdks/java-sdk/java-modules/floating-client.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
