diff --git a/community/lucene-index/src/main/java/org/neo4j/index/lucene/LuceneKernelExtensionFactory.java b/community/lucene-index/src/main/java/org/neo4j/index/lucene/LuceneKernelExtensionFactory.java index 4c80f508369b6..370f7cdc6fdd5 100644 --- a/community/lucene-index/src/main/java/org/neo4j/index/lucene/LuceneKernelExtensionFactory.java +++ b/community/lucene-index/src/main/java/org/neo4j/index/lucene/LuceneKernelExtensionFactory.java @@ -65,7 +65,7 @@ public LuceneKernelExtensionFactory() @Override public Lifecycle newInstance( KernelContext context, Dependencies dependencies ) throws Throwable { - IndexProviders indexProvider = mimicClassWith( IndexProviders.class, dependencies.getIndexProviders() ); + IndexProviders indexProvider = createImposterOf( IndexProviders.class, dependencies.getIndexProviders() ); return new org.neo4j.kernel.api.impl.index.LuceneKernelExtension( context.storeDir(), dependencies.getConfig(), @@ -76,19 +76,31 @@ public Lifecycle newInstance( KernelContext context, Dependencies dependencies ) } /** - * Create a mimicking proxy since it's in the public API and can't be changed + * Create an imposter of an interface. This is effectively used to mimic duck-typing. + * + * @param target the interface to mimic. + * @param imposter the instance of any class, it has to implement all methods of the interface provided by {@code target}. + * @param the type of interface to mimic. + * @param the actual type of the imposter. + * @return an imposter that can be passed as the type of mimicked interface. + * + * @implNote Method conformity is never checked, this is up to the user of the function to ensure. Sharp tool, use + * with caution. */ @SuppressWarnings( "unchecked" ) - private static T mimicClassWith( Class clazz, F base ) + private static T createImposterOf( Class target, F imposter ) { - return (T)Proxy.newProxyInstance( null, new Class[]{clazz}, new MimicWrapper<>( base ) ); + return (T)Proxy.newProxyInstance( target.getClassLoader(), new Class[]{target}, new MirroredInvocationHandler<>( imposter ) ); } - private static class MimicWrapper implements InvocationHandler + /** + * Will pass through everything, as is, to the wrapped instance. + */ + private static class MirroredInvocationHandler implements InvocationHandler { private final F wrapped; - MimicWrapper( F wrapped ) + MirroredInvocationHandler( F wrapped ) { this.wrapped = wrapped; }