LimeLM
wyBuild
Support forum
wyDay blog
wyDay Home

Using TurboActivate with Java

JavaThis article will give step-by-step instructions on how to add software licensing (specifically, hardware-locked or node-locked licensing) to your Java app. There's also a full example app that you can download and play with without needing to add licensing to your app.

By the end of this article you'll have working licensing integrated with your application, and thus the ability to sell individual copies of your software.

Sign up or login and download the native TurboActivate library

Before you can do anything, you need to login to your LimeLM account (or sign up). Then download TurboActivate for Windows, macOS, Linux, or BSD. It contains the native library and source code examples needed to integrate hardware-locked licensing in your Java app:

Adding licensing & online activation to your appTurboActivate.dat and Version GUID

After you've created a new product, go to the version page of the product you will be adding licensing to. You will need to do 2 things:

  1. Download the TurboActivate.dat file for the product version.

  2. Make a note of the Version GUID.

You'll be including the TurboActivate.dat file in a "TurboActivate" folder we'll talk about later and you'll use the Version GUID in your code as part of integrating TurboActivate within your app.

Example project

Included in TurboActivate Library package is a simple Java example project. There are projects for NetBeans, IntelliJ IDEA, and Eclipse. If you're using another IDE you should be able to import one of those projects.

The folder API/Java/src/com/wyday/turboactivate contains all the classes you'll need to add licensing, online-activation, and trial functionality to your app. Copy all those *.java files and add them to your own app.

Step-by-step walkthrough

Now we're going to walk you through each step you need to take in adding licensing, online activation, and timed-trials to your Java app. There are lots of ways you can add licensing to your app, but there are 2 popular styles:

  1. Separate versions of your app. This style of licensing is where you build 2 versions of your product: a trial version and a full version.

  2. Hybrid version of your app. This style of licensing is where your product is the trial version or the full version depending on whether the user is activated.

The first method (the separate versions method) is possible with TurboActivate, but we're not going to talk about it here because it's not very user friendly. Instead we'll talk about making your app a hybrid Full/Trial app. That is, your users will be able to use your app in "trial mode" until either the trial expires or they purchase a product key and use it to activate your app.

Step 1. Signup for LimeLM, download TurboActivate

If you haven't already signed up for LimeLM then sign up now. All plans have a 30-day free trial. Or, if you're just putting your toes in the water, there's even a free plan that has no time limit and doesn't require a credit card.

After you've created your account, download TurboActivate and extract it anywhere. After you extract it you'll find 4 folders:

Step 2. Add TurboActivate classes to your project

Now you need to add TurboActivate to your app. The easiest way to do that is to just copy the "src/com/wyday/turboactivate" directory to your app (with all the containing *.java files).

Step 3. Add JNA (Java Native Access) to your project

The TurboActivate Java classes make use of JNA (Java Native Access). Simply put, JNA is a free library that allows easy access to native libraries (*.dll on Windows, *.dylib on macOS, *.so on Unix) without writing anything but Java code. The best part is we've written native libraries for all major Operating Systems and the accompanying Java code to use it. All you need to do is add the files to your product.

Step 4. Create a new product in LimeLM

If you haven't already created a new product in LimeLM, do it now. You can change any value later, so don't worry about making a mistake.

Adding your first product to LimeLM

Step 5. Download TurboActivate.datTurboActivate.dat and Version GUID

Go to your version page in LimeLM. Download the "TurboActivate.dat" file. You'll be using this file in the next step.

Step 6. Add TurboActivate binaries for Windows, Mac, and Linux

TurboActivate is compiled as a native binary. This means you will need to include the native TurboActivate binaries for every platform you want to support.

The Java TurboActivate package looks for the native platform libraries in the folder "TurboActivate" relative to your .jar file. For instance:

YourApp.jar
TurboActivate/
     TurboActivate.dat
     win-x86/
          TurboActivate.dll
     win-x64/
          TurboActivate.dll
     win-arm64/
          TurboActivate.dll
     mac/
          libTurboActivate.dylib
     linux-i386/
          libTurboActivate.so
     linux-amd64/
          libTurboActivate.so
     linux-arm/
          libTurboActivate.so
     linux-arm64/
          libTurboActivate.so
     freebsd-i386/
          libTurboActivate.so
     freebsd-amd64/
          libTurboActivate.so
     ...

If you're creating platform specific installers then you don't need to include the versions of TurboActivate not applicable to that platform. In other words, if you're releasing your Java app to Windows and to Mac you will likely create a separate installer for each platform.

If you only include the platform specific TurboActivate binaries you will reduce the size of your initial distribution.

Step 7. Creating the TurboActivate instance

Now, inside your app, you need to create a new TurboActivate object with the Version GUID found on the same page you downloaded the TurboActivate.dat from. In the example app we define the "ta" variable in the "main form" class, and then create the TurboActivate object in the form's constructor:

public class frmMain extends JFrame {

    private TurboActivate ta = null;

    public frmMain()
    {
        initComponents();

        try
        {
            //TODO: goto the version page at LimeLM and
            // paste this GUID here
            ta = new TurboActivate("Paste GUID Here");

            // ...

Replace the "Paste GUID Here" string with the Version GUID string your copied from your version page.

Step 8. Checking if the customer is genuinely activated

There are many ways you can use TurboActivate to add licensing to your application. For this example we're going to keep it simple.

Scroll up to your form constructor code and add a "bool" "isGenuine" variable to save whether the customer is activated and genuine. And then it's simply a matter of making a call to IsGenuine() to see if the user is activated and to re-verify the activation with the LimeLM servers every 90 days, with a 14 day grace period:

private TurboActivate ta = null;
boolean isGenuine;

// Don't use 0 for either of these values.
// We recommend 90, 14. But if you want to lower the values we don't recommend going
// below 7 days for each value. Anything lower and you're just punishing legit users.
private static final int DaysBetweenChecks = 90;
private static final int GracePeriodLength = 14;

public frmMain()
{
    initComponents();

    try
    {
        //TODO: goto the version page at LimeLM and
        // paste this GUID here
        ta = new TurboActivate("Paste GUID Here");

        // Check if we're activated, and every 90 days verify it with the activation servers
        // In this example we won't show an error if the activation was done offline
        // (see the 3rd parameter of the IsGenuine() function)
        // https://wyday.com/limelm/help/offline-activation/
        IsGenuineResult gr = ta.IsGenuine(DaysBetweenChecks, GracePeriodLength, true, false);

        isGenuine = gr == IsGenuineResult.Genuine ||
                    gr == IsGenuineResult.GenuineFeaturesChanged ||

                    // an internet error means the user is activated but
                    // TurboActivate failed to contact the LimeLM servers
                    gr == IsGenuineResult.InternetError;


        // If IsGenuineEx() is telling us we're not activated
        // but the IsActivated() function is telling us that the activation
        // data on the computer is valid (i.e. the crypto-signed-fingerprint matches the computer)
        // then that means that the customer has passed the grace period and they must re-verify
        // with the servers to continue to use your app.

        //Note: DO NOT allow the customer to just continue to use your app indefinitely with absolutely
        //      no reverification with the servers. If you want to do that then don't use IsGenuine() or
        //      IsGenuineEx() at all -- just use IsActivated().
        if (!isGenuine && ta.IsActivated())
        {
            // We're treating the customer as is if they aren't activated, so they can't use your app.

            // However, we show them a dialog where they can reverify with the servers immediately.

            ReVerifyNow frmReverify = new ReVerifyNow(this, true, ta, DaysBetweenChecks, GracePeriodLength);
            frmReverify.setLocationRelativeTo(this);

            frmReverify.pack();
            frmReverify.setVisible(true);

            if (frmReverify.getReturnStatus() == TrialExtension.RET_OK)
            {
                isGenuine = true;
            }
            else if (!frmReverify.noLongerActivated) // the user clicked cancel and the user is still activated
            {
                // Just bail out of your app
                System.exit(1);
                return;
            }
        }
    }
    catch (Exception e)
    {
        JOptionPane.showMessageDialog(null, "Failed to check if activated: " + e.getMessage(), "Failed basic activation check", JOptionPane.ERROR_MESSAGE);
        System.exit(1);
        return;
    }

    // Show a trial if we're not genuine
    // See step 10, below.
    ShowTrial(!isGenuine);
}

This is a complete example showing how to check if the customer is genuinely activated, and how to handle the error cases. While it's longer than "toy" licensing solutions, it's built for the real world.

The code does the following:

  1. It creates the new TurboActivate instance with your Version GUID.

  2. Checks if the customer is activated and re-verifies with the servers every 90 days (with a 14-day grace period).

  3. And if IsGenuine(x, y, z) tells you the customer is not genuine then you can use IsActivated() to determine if they're "not genuine" because they were never activated or if it's because the customer has gone more than DaysBetweenChecks + GracePeriodLength days since re-verifying with the activation servers.

  4. And if it's a case where the customer must re-verify with the activation servers, then show a form that lets them do that (also included in the example project).

Step 9. Prompting for the user's product key

If the user has never activated, or if they've since deactivated, then you'll need to prompt the user to enter their product key. You can do this a couple of ways, in this example we'll just use a simple form ("PKey") to prompt the customer to enter their product key.

The first thing you need to do is a new Activate/Deactivate menu to your form. You can name it anything you want — in this example we call it mnuActDeact:

Add Activate/Deactivate menu to your app

After you've created the menu item, changed the name to mnuActDeact in the properties window, click the "Events" tab, then double click the "actionPerformed" event and NetBeans will automatically generate the event code for you:

Activate menu click event

Now we need to handle when the user clicks the Activate/Deactivate menu that you created. Scroll down to the "mnuActDeact_Click" function that NetBeans generated for you. You can add code to Deactivate if the user is activated, or launch the "PKey" form if the user isn't activated:

private void mnuActDeact_Click(java.awt.event.ActionEvent evt)
{
    try
    {
        if (isGenuine)
        {
            // deactivate product without deleting the product key
            // allows the user to easily reactivate
            ta.Deactivate(false);
            isGenuine = false;
            ShowTrial(true);
        }
        else
        {
            // use a simple activation interface
            PKey pkeyBox = new PKey(this, true, ta);
            pkeyBox.setLocationRelativeTo(this);

            pkeyBox.pack();
            pkeyBox.setVisible(true);

            // recheck if activated
            if (pkeyBox.getReturnStatus() == PKey.RET_OK && ta.IsActivated())
            {
                isGenuine = true;
                ReEnableAppFeatures();
                ShowTrial(false);
            }
        }
    }
    catch (Exception e)
    {
        JOptionPane.showMessageDialog(null, "Failed to activate" + e.getMessage(), "Failed to activate", JOptionPane.ERROR_MESSAGE);
    }
}

Step 10. Adding trial functionality

In other parts of this example you've seen references to a ShowTrial() function. This is a function that you'll need to create to add trial functionality to your app. In this example we're going to use verified trials (because they are accurate, fast, and allows you to track conversion of customers).

The first step is to actually tell TurboActivate you'll be using verified trials. Create a trialFlags at the top of your main form that will store this information:

private TurboActivate ta = null;
boolean isGenuine;

// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
private int trialFlags = TurboActivate.TA_SYSTEM | TurboActivate.TA_VERIFIED_TRIAL;

// Don't use 0 for either of these values.
// We recommend 90, 14. But if you want to lower the values we don't recommend going
// below 7 days for each value. Anything lower and you're just punishing legit users.
private static final int DaysBetweenChecks = 90;
private static final int GracePeriodLength = 14;

public frmMain()
{
    initComponents();

    // ...
}

Now we have to make a few functions:

  1. ShowTrial(bool show)

  2. DisableAppFeatures()

  3. ReEnableAppFeatures()

In the ShowTrial method you can show how many trial days remain for the user. You can open the Java example from TurboActivate package if you want to see a full example. Here we'll set the activate menu text to either "Activate" or "Deactivate" and will disable the app features if there are no more trial days remaining:

final void ShowTrial(boolean show)
{
    lblTrialMessage.setVisible(show);
    btnExtendTrial.setVisible(show);
    mnuActDeact.setText(show ? "Activate..." : "Deactivate");

    if (show)
    {
        int trialDaysRemaining = 0;

        try
        {
            ta.UseTrial(trialFlags);

            // get the number of remaining trial days
            trialDaysRemaining = ta.TrialDaysRemaining(trialFlags);
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Failed to start the trial: " + e.getMessage(), "Failed to start the trial", JOptionPane.ERROR_MESSAGE);
        }

        // if no more trial days then disable all app features
        if (trialDaysRemaining == 0)
            DisableAppFeatures();
        else
            lblTrialMessage.setText("Your trial expires in " + trialDaysRemaining + " days.");
    }
}

Now you can add the functions to your code to disable and enable your application features:

void DisableAppFeatures()
{
    //TODO: disable all the features of the program
}

void ReEnableAppFeatures()
{
    //TODO: re-enable all the features of the program
}

In the example Java project the app "feature" we enable/disable is the text box. Obviously you need to tailor this to your specific application.

Now that we have the foundation set we can actually start calling these functions. Scroll back up to the form's constructor and add the call to the ShowTrial() function:

public frmMain()
{
    initComponents();

    try
    {
        ta = new TurboActivate("Paste GUID Here");

        // ... IsGenuine() code from above goes here
    }
    catch (TurboActivateException ex) { /* Handle exception */ }

    ShowTrial(!isGenuine);
}