'. '

ObfuscatePerLibrary

From APIDesign

Revision as of 06:22, 24 October 2014 by JaroslavTulach (Talk | contribs)
Jump to: navigation, search

In contrast to other efforts that try to bring Java back to browser, the Bck2Brwsr VM supports per JAR file compilation, including obfuscation (via Closure compiler). This keeps the dynamic nature of Java, when you compile units independently and them link them into final application on application start. I believe this is way better than classic static obfuscation mode when whole application is converted into a gigantic static JavaScript (like GWT and currently also TeaVM does).

Contents

Exported Packages

Right now Bck2brwsr requires presence of OSGi headers in manifest. Only packages enumerated in Export-Package get exported and can be used by other JAR files. All other classes remain internal to the JAR file - they can be used from other classes in the JAR, but are hidden externally. This allows us to use full obfuscation mode for these classes - e.g. completely rename their class, method or field names. This leads to much shorter code and faster download times.

Faster Compilation

Per library obfuscation may also speed up compilation. Your libraries can be compiled just once and when you build your application you can re-use them and compile only classes of your application. This is possible now when invoking the Bck2Brwsr compiler manually (see ahead-of-time section in Bck2BrwsrJavadoc), but the preconfigured Maven plugin still compiles the whole application as of Oct 2014.

Fast and Parallel Downloading

When one sets up the Bck2Brwsr VM by calling

var vm = bck2brwsr(['library1.jar', 'library2.jar', 'app.jar'])
vm.loadClass('app.MainClass').invoke('main');

the VM loads appropriate 'library1.js' & co. on background and in parallel. Once they are all available specified application class is loaded and its method is invoked.

Per library obfuscation is a way to minimize download time, as popular libraries can be hosted on a single website and shared between different applications. Then browsers can cache them and minimize the time needed to start Bck2Brwsr any application. Bck2Brwsr Maven archetype does not automate this currently, however.

Deployment

Browsers are optimized for consuming JavaScript (compressed by GZip). We tried to use ZIP, but it was not the most effective solution. That is why our current maven archetype generates alternative .js file for per JAR file. If the JavaScript file is found, let bck2brwsr use it. If not, let [bck2brwsr]] downloads and use the JAR file.

Design

Define @Exported annotation to put on packages, classes, methods. This exported elements need to stick to fixed identifier.

Do as much calls as possible inside a library with obfuscated names. Private, package private methods should be obfuscated (unless @Exported). Classes in non-exported packages can have everything obfuscated (unless implement exported symbol). Exported classes should generate something like this:

function org_nb_test_Clazz() {
 
}
vm['org/nb/test/Clazz'] = org_nb_test_Clazz;

public or protected non-final methods need to be exported in an overridable style:

function org_nb_test_Clazz() {
  var p = ...;
 
  org_nb_test_Clazz.impl_myFunction_V = function () { ... };
 
  p['myFunction_V'] = org_nb_test_Clazz.impl_myFunction_V;
  org_nb_test_Clazz.myFunction_V = function() { return this['myFunction_V'](); }
}

Need to generate JavaScript which can be loaded into Bck2Brwsr VM. E.g. the actual vm object is already created and need to be passed to the generated script. The script assumes existence of method registerLibrary in the calling context:

registerLibrary(/*['dep','anotherDep','moreDep']*/, function (vm) {
  // when invoked register all own classes and their methods into the vm object
});

As soon as one does var vm = bck2brwsr(...) all the provided libraries will be loaded.

TODO

  • Introduce @Exported annotation and modify obfuscation to also mange package private members (Ľubo)
  • Encode resources from a JAR into JavaScript. Probably via wikipedia:base64 (Jarda)
  • Modify Maven task to process single JAR in a batch
Personal tools
buy