# Using The CLI
Your generated project provides an internationalized Command Line Interface (CLI) for the Key Generator and the Key
Manager modules.
The CLI gets implemented in the main classes ${package}.keygen.Main
and ${package}.keymgr.Main
, respectively.
# Using The Key Generator CLI
# Overview
If you run the standalone JAR of the Key Generator module without parameters, it prints usage instructions:
$ java -jar keygen/target/*-keygen-*-standalone.jar
Usage:
Main <command> [<options>] [<parameters>]
where <command> is one of (case is ignored):
help print usage instructions for a command
version print version information
generate generates a license key
You can get help for a particular command by using the help
command.
These are the usage instructions for the generate
command:
$ java -jar keygen/target/*-keygen-*-standalone.jar help generate
Usage:
generate [[-key] <license-key-path> ] |
[-input <input-license-path> ] |
[-output <output-license-path>] |
[-edition <edition>] |
[-verbose <boolean>]
Generates a license key and prints its license bean to standard output. If a
<license-key-path> is specified, then the generated license key gets saved to
the file identified by this path.
If an <input-license-path> is specified, then the license bean gets decoded
from the file identified by this path and transformed into the license key.
Specifying a dash (-) causes the standard input stream to be used instead of a
file. If no <input-license-path> is specified, then a default license bean gets
created and transformed into the license key.
If an <output-license-path> is specified, then the license bean gets encoded to
the file identified by this path for subsequent editing and input to this
command. Specifying a dash (-) causes the standard output stream to be used
instead of a file.
If more than edition has been configured in the licensing schema, then a
<edition> must be specified on the command line.
By default, this command does not write debugging information to the standard
error stream. You can override the default behavior by specifying
`-verbose true` or `-verbose false`.
# Generating A License Key
# Using Default Properties
You can generate a license key with default properties as follows:
$ java -jar keygen/target/*-keygen-*-standalone.jar generate product.lic -verbose true
global.namespace.truelicense.v4.V4License@ce3c1e26[subject="StarGazer 2020", holder="CN=Unknown", issuer="CN=Company Inc.", issued=Sat May 23 18:46:11 CEST 2020, notBefore=null, notAfter=null, consumerType="User", consumerAmount=1, info=null]
This command creates and initializes a new license bean, encodes it into a license key and writes the result into the
file product.lic
.
If the property ${verboseCli}
is set to true
when generating your project, then a brief representation of the
encoded license bean gets printed to the standard error stream by default.
You can override this by specifying -verbose true
or -version false
.
# Supporting Multiple Editions
If your software product requires supporting multiple editions, then you need to specify the -edition
option on the
command line.
For example, you can generate a license key for an edition named standard
like this:
$ java -jar keygen/target/*-keygen-*-standalone.jar generate product.lic -verbose true -edition standard
global.namespace.truelicense.v4.V4License@9628f7d5[subject="StarGazer 2020", holder="CN=Unknown", issuer="CN=Company Inc.", issued=Sat May 23 18:49:29 CEST 2020, notBefore=null, notAfter=null, consumerType="User", consumerAmount=1, info=null]
For brevity, only one edition is assumed in the remainder of this page, so this option is not specified again.
# Property Input
You can specify the -input
parameter in order to read a template license bean from a file or the standard input
stream.
The input syntax needs to conform to the configured license key format.
For example, if the license key format is V4, then you can decode a license bean with the holder
and term
properties from the standard input stream in JSON format and generate a V4 license key from it like this:
$ echo '{ "holder": "CN=Christian Schlichtherle", "term": 365 }' | \
java -jar keygen/target/*-keygen-*-standalone.jar generate product.lic -verbose true -input -
global.namespace.truelicense.v4.V4License@752005ff[subject="StarGazer 2020", holder="CN=Christian Schlichtherle", issuer="CN=Company Inc.", issued=Sat May 23 18:55:08 CEST 2020, notBefore=Sat May 23 18:55:08 CEST 2020, notAfter=Sun May 23 18:55:08 CEST 2021, consumerType="User", consumerAmount=1, info=null]
Please refer to the Javadoc for the interface global.namespace.truelicense.api.License
for a list of all properties.
# Property Output
You can specify the -output
parameter in order to write the encoded license bean to a file or the standard output
stream.
The output syntax conforms to the configured license key format.
For example, if the license key format is V4, then you can decode a license bean with the issuer
property from
the standard input stream in JSON format, generate a V4 license key from it and print the encoded license bean to
the standard output stream like this:
$ echo '{ "issuer": "CN=Christian Schlichtherle" }' | \
java -jar keygen/target/*-keygen-*-standalone.jar generate product.lic -verbose false -input - -output -
{"consumerAmount":1,"consumerType":"User","holder":"CN=Unknown","issued":1590253080694,"issuer":"CN=Christian Schlichtherle","subject":"StarGazer 2020"}
# Custom Properties
Besides the predefined properties, you can also store custom properties in a license bean.
To facilitate this, the License
interface defines a property with the name extra
and the type java.lang.Object
.
To store an object into this property, its type needs to be supported by the codec of the respective license key format,
i.e. JSON or XML.
Both codecs support java.util.Map
without customization.
For example, if the license key format is V4, then you can provide a map with the custom properties named foo
and
bar
like this:
$ echo '{ "extra": { "foo": 1, "bar": "baz" } }' | \
java -jar keygen/target/*-keygen-*-standalone.jar generate product.lic -verbose false -input - -output -
{"consumerAmount":1,"consumerType":"User","extra":{"foo":1,"bar":"baz"},"holder":"CN=Unknown","issued":1590253228724,"issuer":"CN=Company Inc.","subject":"StarGazer 2020"}
TrueLicense never discloses the property extra
to users, so you can store any private information in it.
If you want to share some additional information with the user, then you can use the property with the name info
and
the type java.lang.String
instead.
# Using The Key Manager CLI
# Overview
Just like the standalone JAR of the Key Generator module, if you run the guarded JAR or the standalone JAR of the Key Manager module without parameters, it prints usage instructions:
$ java -jar keymgr/target/*-keymgr-*-guarded.jar
Usage:
Main <command> [<options>] [<parameters>]
where <command> is one of (case is ignored):
help print usage instructions for a command
version print version information
install installs a license key
load loads and prints the installed license key
verify verifies the installed license key
uninstall Uninstalls the license key
wizard starts the licensing wizard
You can get help for a particular command by using the help
command.
These are the usage instructions for the install
command:
$ java -jar keymgr/target/*-keymgr-*-guarded.jar help install
Usage:
install <license-key-path>
Loads and installs the regular license key from the file identified by
<license-key-path>.
TIP
The following examples use the keymgr-*-standalone.jar
, i.e. the unobfuscated JAR to produce readable output.
Try these commands with the keymgr-*-guarded.jar
and notice the difference for yourself.
# Installing A License Key
You can install a license key as follows:
$ java -jar keymgr/target/*-keymgr-*-standalone.jar install product.lic
Note that there is no output unless there is an error, in which case an exception gets printed.
# Loading The License Key
You can load the installed license key as follows:
$ java -jar keymgr/target/*-keymgr-*-standalone.jar load
global.namespace.truelicense.v4.V4License@9a7e2266[subject="StarGazer 2020", holder="CN=Unknown", issuer="CN=Company Inc.", issued=Sat May 23 19:00:28 CEST 2020, notBefore=null, notAfter=null, consumerType="User", consumerAmount=1, info=null]
A brief representation of the encoded license bean gets written to the standard output stream.
If no license key is installed, then a global.namespace.truelicense.api.LicenseManagementException
gets thrown instead
$ java -jar keymgr/target/*-keymgr-*-standalone.jar load
global.namespace.truelicense.api.LicenseManagementException: global.namespace.fun.io.api.NoContentException: Cannot locate the key "StarGazer 2020" in the user preferences node for the absolute path "/com/company/product/keymgr".
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:83)
at global.namespace.truelicense.core.TrueLicenseManagementContext.access$800(TrueLicenseManagementContext.java:37)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.load(TrueLicenseManagementContext.java:758)
at com.company.product.keymgr.LicenseManager.load(LicenseManager.java:94)
at com.company.product.keymgr.Main$5.run(Main.java:54)
at com.company.product.keymgr.Main.process(Main.java:120)
at com.company.product.keymgr.Main.processAndHandleExceptions(Main.java:102)
at com.company.product.keymgr.Main.main(Main.java:96)
Caused by: global.namespace.fun.io.api.NoContentException: Cannot locate the key "StarGazer 2020" in the user preferences node for the absolute path "/com/company/product/keymgr".
at global.namespace.fun.io.bios.PreferencesStore.content(PreferencesStore.java:80)
at global.namespace.fun.io.api.Store.content(Store.java:76)
at global.namespace.fun.io.bios.PreferencesStore.lambda$input$0(PreferencesStore.java:43)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.truelicense.core.Filters$1.lambda$input$1(Filters.java:51)
at global.namespace.fun.io.api.Socket.apply(Socket.java:123)
at global.namespace.fun.io.jackson.JsonCodec$1.decode(JsonCodec.java:44)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.repositoryModel(TrueLicenseManagementContext.java:810)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.repositoryController(TrueLicenseManagementContext.java:804)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.authenticate(TrueLicenseManagementContext.java:800)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$CachingLicenseManager.authenticate(TrueLicenseManagementContext.java:673)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.decodeLicense(TrueLicenseManagementContext.java:796)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.lambda$load$2(TrueLicenseManagementContext.java:760)
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:79)
... 7 more
# Verifying The License Key
You can verify the installed license key using:
$ java -jar keymgr/target/*-keymgr-*-standalone.jar verify
Note that there is no output in case of success.
If no license key is installed however, then a global.namespace.truelicense.api.LicenseManagementException
gets thrown
instead:
$ java -jar keymgr/target/*-keymgr-*-standalone.jar verify
global.namespace.truelicense.api.LicenseManagementException: global.namespace.fun.io.api.NoContentException: Cannot locate the key "StarGazer 2020" in the user preferences node for the absolute path "/com/company/product/keymgr".
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:83)
at global.namespace.truelicense.core.TrueLicenseManagementContext.access$800(TrueLicenseManagementContext.java:37)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.verify(TrueLicenseManagementContext.java:766)
at com.company.product.keymgr.LicenseManager.verify(LicenseManager.java:99)
at com.company.product.keymgr.Main$6.run(Main.java:59)
at com.company.product.keymgr.Main.process(Main.java:120)
at com.company.product.keymgr.Main.processAndHandleExceptions(Main.java:102)
at com.company.product.keymgr.Main.main(Main.java:96)
Caused by: global.namespace.fun.io.api.NoContentException: Cannot locate the key "StarGazer 2020" in the user preferences node for the absolute path "/com/company/product/keymgr".
at global.namespace.fun.io.bios.PreferencesStore.content(PreferencesStore.java:80)
at global.namespace.fun.io.api.Store.content(Store.java:76)
at global.namespace.fun.io.bios.PreferencesStore.lambda$input$0(PreferencesStore.java:43)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.truelicense.core.Filters$1.lambda$input$1(Filters.java:51)
at global.namespace.fun.io.api.Socket.apply(Socket.java:123)
at global.namespace.fun.io.jackson.JsonCodec$1.decode(JsonCodec.java:44)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.repositoryModel(TrueLicenseManagementContext.java:810)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.repositoryController(TrueLicenseManagementContext.java:804)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.authenticate(TrueLicenseManagementContext.java:800)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$CachingLicenseManager.authenticate(TrueLicenseManagementContext.java:673)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.decodeLicense(TrueLicenseManagementContext.java:796)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$CachingLicenseManager.validate(TrueLicenseManagementContext.java:662)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.lambda$verify$3(TrueLicenseManagementContext.java:768)
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:79)
... 7 more
If a license key is installed, but the encoded license bean is invalid, then a
global.namespace.truelicense.api.LicenseValidationException
gets thrown instead:
$ java -jar keymgr/target/*-keymgr-*-standalone.jar verify
global.namespace.truelicense.api.LicenseValidationException: License validity period has expired at Sunday, 17 May 2020 19:31:26 Central European Summer Time.
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseValidation.validate(TrueLicenseManagementContext.java:908)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$CachingLicenseManager.validate(TrueLicenseManagementContext.java:665)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.lambda$verify$3(TrueLicenseManagementContext.java:768)
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:79)
at global.namespace.truelicense.core.TrueLicenseManagementContext.access$800(TrueLicenseManagementContext.java:37)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.verify(TrueLicenseManagementContext.java:766)
at com.company.product.keymgr.LicenseManager.verify(LicenseManager.java:99)
at com.company.product.keymgr.Main$6.run(Main.java:59)
at com.company.product.keymgr.Main.process(Main.java:120)
at com.company.product.keymgr.Main.processAndHandleExceptions(Main.java:102)
at com.company.product.keymgr.Main.main(Main.java:96)
# Uninstalling The License Key
You can uninstall the license key using:
$ java -jar keymgr/target/*-keymgr-*-standalone.jar uninstall
Note that there is no output unless there is an error, in which case an exception gets printed.
If no license key is installed or only an auto-generated FTP license key is installed, then a
global.namespace.truelicense.api.LicenseManagementException
gets thrown instead:
$ java -jar *-keymgr/target/*-keymgr-*-standalone.jar uninstall
global.namespace.truelicense.api.LicenseManagementException: global.namespace.fun.io.api.NoContentException: Cannot locate the key "StarGazer 2020" in the user preferences node for the absolute path "/com/company/product/keymgr".
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:83)
at global.namespace.truelicense.core.TrueLicenseManagementContext.access$800(TrueLicenseManagementContext.java:37)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.uninstall(TrueLicenseManagementContext.java:775)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$CachingLicenseManager.uninstall(TrueLicenseManagementContext.java:651)
at com.company.product.keymgr.LicenseManager.uninstall(LicenseManager.java:104)
at com.company.product.keymgr.Main$7.run(Main.java:64)
at com.company.product.keymgr.Main.process(Main.java:120)
at com.company.product.keymgr.Main.processAndHandleExceptions(Main.java:102)
at com.company.product.keymgr.Main.main(Main.java:96)
Caused by: global.namespace.fun.io.api.NoContentException: Cannot locate the key "StarGazer 2020" in the user preferences node for the absolute path "/com/company/product/keymgr".
at global.namespace.fun.io.bios.PreferencesStore.content(PreferencesStore.java:80)
at global.namespace.fun.io.api.Store.content(Store.java:76)
at global.namespace.fun.io.bios.PreferencesStore.lambda$input$0(PreferencesStore.java:43)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.fun.io.api.Socket.lambda$map$0(Socket.java:136)
at global.namespace.truelicense.core.Filters$1.lambda$input$1(Filters.java:51)
at global.namespace.fun.io.api.Socket.apply(Socket.java:123)
at global.namespace.fun.io.jackson.JsonCodec$1.decode(JsonCodec.java:44)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.repositoryModel(TrueLicenseManagementContext.java:810)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.repositoryController(TrueLicenseManagementContext.java:804)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.authenticate(TrueLicenseManagementContext.java:800)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$CachingLicenseManager.authenticate(TrueLicenseManagementContext.java:673)
at global.namespace.truelicense.core.TrueLicenseManagementContext$TrueLicenseManagerParameters$TrueLicenseManager.lambda$uninstall$4(TrueLicenseManagementContext.java:781)
at global.namespace.truelicense.core.TrueLicenseManagementContext.callChecked(TrueLicenseManagementContext.java:79)
... 8 more