How not to add one more jar to your classpath

Let me start with a little java test.
The following code prints “Hi, There” 
Can you explain how it does that ?

public class Test {
public static void main(String args[]) {
try {
new ClassLoader() {
public Class<?> findClass(String c) {
byte[] bytecode = java.util.Base64.getDecoder().decode(
"yv66vgAAADQAGAoABgAKCQALAAwIAA0KAA4ADwcAEAcAEQEABjxpb"+
"l0PgEAAygpVgEABENvZGUMAAcACAcAEgwAEwAUAQAJSGksIHRoZXJ"+
"lBwAVDAAWABcBAAFBAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEv"+
"bGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhb"+
"TsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMam"+
"F2YS9sYW5nL1N0cmluZzspVgAhAAUABgAAAAAAAQABAAcACAABAAk"+
"AAAAZAAIAAQAAAA0qtwABsgACEgO2AASxAAAAAAAA");
return defineClass(“A”, bytecode, 0, bytecode.length);
}
}.loadClass(“A”).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

The answer is:
It does so by creating a new class A and by instantiating it. Of course, Class A looks something like this:

public class A {
public A() {
System.out.println(“Hi, there”);
}
}

although, regrettably, in Test.java you cannot really see much of its code.

It is however there, presented in its raw format (bytecode) encoded in a base64 string.

If you wonder, the string representation for A as it appears in Test.java can be generated by compiling A.java and then accessing like this:

URL url = A.class.getResource("A.class");
byte array[] = Files.readAllBytes(Paths.get(url.toURI()));
String bytecode = Base64.getEncoder().encodeToString(array);
System.out.println(bytecode); // this prints yv66vgAAADQAGAoAB…

What’s the point ?

So, aside from making our code impossible to read (which is very bad), is there any benefit in dealing with raw bytecode like this ? 
 
Well, since you can encode bytecode into a piece of code you can now take a different approach on distributing your work and ask people to copy and paste a snippet of code inside their java program instead of downloading a jar.

Surely, this approach is not for everybody but it might be worthwhile in a few cases:

  1. “try-before-you-use” demos
  2. Some specialised solutions where:
    - Your library is ultra light and has no dependencies (or only dependencies you can assume being present in the environment when it gets integrated)
    - Your API is minimal.
    - Your tool’s service is purely additive (such as is the case for monitoring apps, profilers, coverage analyzers, event loggers, etc. ).

A real example

I have used this approach in nudge4j.
nudge4j is a monitoring tool for java applications which is typically used during development. 
A copy/paste approach to me seemed ideal.

Thanks for reading this.