Skip to content

Instantly share code, notes, and snippets.

@raphw
Last active January 11, 2020 21:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save raphw/be0994259e75652f057c9e1d3ee5f567 to your computer and use it in GitHub Desktop.
Save raphw/be0994259e75652f057c9e1d3ee5f567 to your computer and use it in GitHub Desktop.
Example of a shadingproof JNI binding.
package com.shadeproof;
import net.bytebuddy.ByteBuddy;
public abstract class NativeBinding {
public static final NativeBinding INSTANCE;
static {
System.load("mylibrary");
String expected = "!com!shadeproof!NativeBinding!";
expected = expected.substring(1, expected.length() - 1).replace('!', '.');
if (NativeBinding.class.getName().equals(expected)) {
INSTANCE = new DirectNativeBinding();
} else {
try {
INSTANCE = new ByteBuddy()
.redefine(DirectNativeBinding.class)
.name(expected)
.make()
.load(NativeBinding.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded()
.getConstructor()
.newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}
public abstract void method();
private static class DirectNativeBinding extends NativeBinding {
public native void method();
}
}
@raphw
Copy link
Author

raphw commented Dec 7, 2019

Lacks ClassLoadingStrategy.Default.INJECTION, loading native code only works for the same class loader, the hierarchy is not applied for those.

@felixbarny
Copy link

ClassLoadingStrategy.Default.INJECTION does not work if the target class loader contains a non-shaded version as well as a shaded version, therefore ClassLoadingStrategy.Default.CHILD_FIRST seems more appropriate. To make sure the native library is loaded from the child class loader, it should be loaded form the static initializer of the DirectNativeBinding class. See also https://gist.github.com/felixbarny/3f519ac49520018aa8ecc82cae352670

@raphw
Copy link
Author

raphw commented Jan 11, 2020

Indeed, have not considered that case. Thanks for the hint, I'll keep it in the back in my head if I run into that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment