THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
...
Code Block | ||
---|---|---|
| ||
public class ClassLoaderPessimisticCodec implements ClassLoaderCodec { private static final byte FRAMEWORK_CLASS_LOADER_ID = 0; private static final byte IGNITE_CLASS_LOADER_ID = 1; private static final byte BOOT_CLASS_LOADER_ID = 2; private static final byte BUNDLE_CLASS_LOADER_ID = 4; private static final ClassLoader FRAMEWOR_CLASS_LOADER = Bundle.class.getClassLoader(); private final PackageAdmin packageAdmin; public ClassLoaderPessimisticCodec(PackageAdmin packageAdmin) { this.packageAdmin = packageAdmin; } @Nullable @Override public Object encodeClassLoader(Class<?> cls) throws IgniteException { ClassLoader classLoader = cls.getClassLoader(); if (isIgniteClass(classLoader)) { return ClassLoaderDesc.newIgniteClassLoaderDesc(); } if (isFrameworkClassLoader(cls.getClassLoader())) { return ClassLoaderDesc.newFrameworkClassLoader(); } Bundle bundle = FrameworkUtil.getBundle(cls); if (bundle != null) { return ClassLoaderDesc.newBundleClassLoaderDesc(bundle); } return ClassLoaderDesc.newBootClassLoader(); } @Nullable private Bundle getBundleExt(Class<?> cls) { // maybe handle SecurityManager Bundle bundle = FrameworkUtil.getBundle(cls); if (bundle == null && isFrameworkClassLoader(cls.getClassLoader())) { bundle = FrameworkUtil.getBundle(Bundle.class); } return bundle; } @Override public ClassLoader decodeClassLoader(String fqn, ClassLoader clsLdr, @Nullable Object encodedClsLdr) throws IgniteException { ClassLoaderDesc classLoaderDesc = (ClassLoaderDesc) encodedClsLdr; switch (classLoaderDesc.classLoaderId) { case BOOT_CLASS_LOADER_ID: return clsLdr; case FRAMEWORK_CLASS_LOADER_ID: return FRAMEWOR_CLASS_LOADER; case IGNITE_CLASS_LOADER_ID: return ClassLoaderCodec.class.getClassLoader(); case BUNDLE_CLASS_LOADER_ID: //strict version but we can think about an different strategy here like minor or micro version range packageAdmin.getBundles(classLoaderDesc.bsn, classLoaderDesc.version); } return null; } static final class ClassLoaderDesc implements Externalizable { private String version; private String bsn; private byte classLoaderId; public ClassLoaderDesc() {} public ClassLoaderDesc(byte classLoaderId) { this.classLoaderId = classLoaderId; } public ClassLoaderDesc(Bundle bundle) { this.classLoaderId = BUNDLE_CLASS_LOADER_ID; this.bsn = bundle.getSymbolicName(); this.version = bundle.getVersion().toString(); } @Override public void writeExternal(ObjectOutput out) throws IOException { out.write(classLoaderId); if (classLoaderId == BUNDLE_CLASS_LOADER_ID) { out.writeUTF(bsn); //can be optimized out.writeUTF(version); } } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { classLoaderId = in.readByte(); if (classLoaderId == BUNDLE_CLASS_LOADER_ID) { } } static ClassLoaderDesc newIgniteClassLoaderDesc() { return new ClassLoaderDesc(IGNITE_CLASS_LOADER_ID); } public static ClassLoaderDesc newBundleClassLoaderDesc(Bundle bundle) { return new ClassLoaderDesc(bundle); } public static ClassLoaderDesc newFrameworkClassLoader() { return new ClassLoaderDesc(FRAMEWORK_CLASS_LOADER_ID); } public static ClassLoaderDesc newBootClassLoader() { return new ClassLoaderDesc(BOOT_CLASS_LOADER_ID); } } } |
Disclaimer: this implementation is not functional and not optimized is purpose it to show how it can be done. Here we are using the PackageAdmin
service which is deprecated but really simple to demonstrate the purpose.