The final step in developing a LuciadLightspeed application is obfuscating the code. This step is required by Hexagon to transition to the deployment phase and brings several benefits for your application:
Protection of the source code of an application from reverse engineering.
Reduction of application footprint. Obfuscated names are shorter and can significantly reduce the application footprint. Obfuscation programs, such as Proguard, also allow for other optimizations. One example is ‘shrinking’ which removes unused byte code. This can also drastically reduce the application footprint. Experiments with Lucy resulted in a functional Lucy application that was less than 4MB in size.
Obfuscating Java class files means replacing the original class names, method names, and field names by short, meaningless
names. For instance, obfuscation may rename a method
double getX() to
double a(). Obfuscation makes it much harder to reverse engineer the code. Although it does not necessarily make decompilation impossible,
understanding the decompiled code becomes more difficult.
Obfuscation also removes the debugging information that is not required for deployment. By default, Java class files still contain all class/method/field/argument/variable names, source file names, and source line numbers. Removing this information typically reduces the footprint of the application by 30% as an interesting side-effect.
In addition, many obfuscating tools further shrink the processed applications by removing classes, methods, and fields that are not actually used in the code. Especially when your are using large APIs like LuciadLightspeed, this operation can considerably reduce the size of the jars.
Your LuciadLightspeed license requires you to obfuscate the class files of the LuciadLightspeed API when you deploy your applications (i.e. application, applet, servlet, …​). This requirement serves as protection against uncontrolled distribution of the API. You are not required to obfuscate your own code, in the sense of changing its class names, method names, and field names, but you will have to process your code together with the LuciadLightspeed API, in order to make sure all references to the LuciadLightspeed API are updated correctly.
When your LuciadLightspeed application has been obfuscated, it is ready to be deployed. You should then replace the developer
license file (
development_license.jar) in your class path by an end user license file (
In these instructions, it is assumed that you are using a recent version of the obfuscation program ProGuard, which we highly recommend.
LuciadLightspeed comes with a collection of sample scripts and ProGuard configuration files that demonstrate how to obfuscate
your application. To use them, download the most recent version of ProGuard and place its
proguard.jar in the
build/proguard folder of the LuciadLightspeed release, next to the configuration files (
The sample deployment scripts are located in
build/lucy. The scripts are written for Ant, which is also included in the release.
You can call the
*.xml scripts directly using Ant, or you can call one of the wrapper shell scripts (
*.sh) to automatically use the bundled Ant. The sections below explain how you can use the scripts for basic obfuscation. For
a more advanced usage, see the documentation in the script source files.
To obfuscate an application with ProGuard, you must specify a few things. The sample scripts take care of all of this and do not require any parameters:
injars: the code to be obfuscated. This means all Luciad jars (
lcd_*.jar) and your own code.
libraryjars: all dependencies of the code. This means all other jars, including the Java run-time libraries.
outjars: a directory or jar file to write the obfuscated result to.
The configuration to use, either specified directly or in a
We suggest using the sample scripts as a guide when obfuscating your own application.
The sample configuration files in
build/proguard specify all required and recommended settings for deploying and obfuscating a LuciadLightspeed-based application. They can
be included in your own configuration with
-include and are also used in the sample scripts mentioned above. If you are modifying or extending these configuration files, take
the following into account:
Obfuscators typically rename all classes by default, making their names unrecognizable. Therefore, at least specify the main class of your application to the obfuscator, so its name can be preserved as an entry point.
The names of classes that are instantiated dynamically, based on their names (using the method
Class.forName), must be preserved. For instance, classes that implement
javax.swing.plaf.ComponentUIare instantiated dynamically, so their names must be kept. LuciadLightspeed also instantiates a number of classes dynamically. For instance, all implementations of
ILcdGXYEditorin the packages
com.luciad.internal.symbologyand sub-packages have to be kept.
You can find a complete list of LuciadLightspeed classes that have to be preserved in the configuration file
luciadlightspeed.pro. You can find a sample configuration for processing all the samples in the file build/proguard/samples.pro. If you are using Lucy, you can find a sample configuration for processing it in the file lucy_end_user.pro.
Below is a list of considerations and common problems during and after obfuscation. Also take a look at ProGuard’s troubleshooting page. If you encounter an unlisted problem that you are unable to solve, contact the Luciad Support Desk services and provide:
A detailed description of the problem, including any stack traces.
An explanation of the steps leading to the problem.
The ProGuard version you used.
Your ProGuard configuration files.
The full obfuscation log. Those are all the messages that ProGuard writes to the console.
- Always use the ProGuard configuration files shipped with the product and version that you are using.
Those files are updated regularly. Using the files of another product, or of an older version, will likely result in errors.
- The ProGuard Maven plugin is not supported.
It is very difficult, if not impossible, to configure this plugin correctly. We recommend against it. Instead, set up obfuscation as a separate step in your build pipeline and use ProGuard directly or through Ant.
- ProGuard does not support multi-release jars.
Multi-release jars were introduced in Java 9, but are not supported by ProGuard. If your application includes or depends on such jars, you must filter out the alternate versions or ProGuard will complain about duplicate definitions.
- Do not shrink or optimize your application.
Shrinking or optimizing your application causes ProGuard to remove what it considers unused code. It discards code too eagerly, however. Using these options in a LuciadLightspeed-based application will cause run-time errors such as
- Always use the latest version of ProGuard.
ProGuard has its own set of issues and gets updated frequently. It is recommended to use the latest version at all times.
- The latest ProGuard version might not support OracleJDK/OpenJDK 11 yet.
If you want to compile and obfuscate using OracleJDK/OpenJDK 11 and the latest ProGuard version does not support this version yet, contact the Luciad Support Desk services.
- Warning message: library class …​ depends on program class …​
This warning is thrown if you have incorrectly split your code into
libraryjars. Make sure that all Luciad jars (
lcd_*.jar) and your own code are specified as injar and other libraries as libraryjar.
- A VerifyError is thrown at run-time.
This can be caused by turning off pre-verification or enabling optimization when running ProGuard. Make sure that
-dontpreverifyis not specified anywhere in your configuration and that
- Classes in
javax.cryptocannot be found.
Make sure that you have specified both
jce.jar(part of the JRE) as libraryjar.
- You get a bunch of NoClassDefFoundErrors, NoSuchMethodErrors, class cast exceptions or similar.
You may be mixing obfuscated and non-obfuscated code. Make sure that your class path includes only obfuscated jars and has no reference to any of the original, non-obfuscated code. Take special care when using wildcards.