The article "Cracking Java byte-code encryption" (javaworld.com/javaworld/javaqa/2003-05/01-qa-0509-jcrypt.html) explains why class file encryption using a custom class loader is pointless, because at some point you always need to call defineClass(), which passes the class file to the JVM as an unencrypted byte array.
However I've seen solutions where a slightly different approach is used; the class is decrypted by a native library and handed over to the JVM as a java.lang.Class instance through the findClass() method -- defineClass() is never called.
Does that mean that these solutions do not have this weakness? Sure, you can always extract class files by working with a debugger on the assembler level, and a determined hacker can break any protection. But at least this makes decompilation a bit more difficult than just patching defineClass() to dump unencrypted .class files to disk. Or am I overlooking something?