Control flow abstraction is essentially the inverse of the task that a compiler performs. The loops both terminate when i equal 1000. These attempt to stop decompilers from operating, by exploiting their weaknesses. The task of making reverse engineering costly is difficult. Client-server models of protection, while providing the best security, suffer from limitations on network capacity.
Encryption requires the use of specialized hardware, in turn limiting the portability of programs.
Using native object codes makes reverse engineering harder but increases the software support effort. Also, digital signatures are required to prevent tampering. Code obfuscation, while not providing absolute security, is portable, does not require specialized hardware and is transparent to the Java bytecode verifier. However, it does impose an execution time-space penalty on the program being protected. Code obfuscation is a fruitful area for further research.