Skip to content

Commit

Permalink
Don't use MethodHandle#invokeWithArguments for UDF
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Feb 28, 2018
1 parent 557636c commit 1fa5463
Showing 1 changed file with 10 additions and 13 deletions.
Expand Up @@ -19,8 +19,8 @@
*/ */
package org.neo4j.kernel.impl.proc; package org.neo4j.kernel.impl.proc;


import java.io.Closeable; import org.apache.commons.lang3.exception.ExceptionUtils;
import java.io.IOException;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method; import java.lang.reflect.Method;
Expand All @@ -36,10 +36,10 @@
import java.util.stream.Stream; import java.util.stream.Stream;


import org.neo4j.collection.RawIterator; import org.neo4j.collection.RawIterator;
import org.neo4j.kernel.api.exceptions.ComponentInjectionException;
import org.neo4j.graphdb.Resource; import org.neo4j.graphdb.Resource;
import org.neo4j.io.IOUtils; import org.neo4j.io.IOUtils;
import org.neo4j.kernel.api.ResourceTracker; import org.neo4j.kernel.api.ResourceTracker;
import org.neo4j.kernel.api.exceptions.ComponentInjectionException;
import org.neo4j.kernel.api.exceptions.KernelException; import org.neo4j.kernel.api.exceptions.KernelException;
import org.neo4j.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.exceptions.ProcedureException;
import org.neo4j.kernel.api.exceptions.ResourceCloseFailureException; import org.neo4j.kernel.api.exceptions.ResourceCloseFailureException;
Expand Down Expand Up @@ -313,7 +313,6 @@ private CallableUserFunction compileFunction( Class<?> procDefinition, MethodHan
List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor( method ); List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor( method );
Class<?> returnType = method.getReturnType(); Class<?> returnType = method.getReturnType();
TypeMappers.NeoValueConverter valueConverter = typeMappers.converterFor( returnType ); TypeMappers.NeoValueConverter valueConverter = typeMappers.converterFor( returnType );
MethodHandle procedureMethod = lookup.unreflect( method );
Optional<String> description = description( method ); Optional<String> description = description( method );
UserFunction function = method.getAnnotation( UserFunction.class ); UserFunction function = method.getAnnotation( UserFunction.class );
Optional<String> deprecated = deprecated( method, function::deprecatedBy, Optional<String> deprecated = deprecated( method, function::deprecatedBy,
Expand All @@ -340,7 +339,7 @@ private CallableUserFunction compileFunction( Class<?> procDefinition, MethodHan
new UserFunctionSignature( procName, inputSignature, valueConverter.type(), deprecated, new UserFunctionSignature( procName, inputSignature, valueConverter.type(), deprecated,
config.rolesFor( procName.toString() ), description ); config.rolesFor( procName.toString() ), description );


return new ReflectiveUserFunction( signature, constructor, procedureMethod, valueConverter, setters ); return new ReflectiveUserFunction( signature, constructor, method, valueConverter, setters );
} }


private CallableUserAggregationFunction compileAggregationFunction( Class<?> definition, MethodHandle constructor, private CallableUserAggregationFunction compileAggregationFunction( Class<?> definition, MethodHandle constructor,
Expand Down Expand Up @@ -716,15 +715,15 @@ private static class ReflectiveUserFunction extends ReflectiveBase implements Ca
private final TypeMappers.NeoValueConverter valueConverter; private final TypeMappers.NeoValueConverter valueConverter;
private final UserFunctionSignature signature; private final UserFunctionSignature signature;
private final MethodHandle constructor; private final MethodHandle constructor;
private final MethodHandle udfMethod; private final Method udfMethod;


ReflectiveUserFunction( UserFunctionSignature signature, MethodHandle constructor, ReflectiveUserFunction( UserFunctionSignature signature, MethodHandle constructor,
MethodHandle procedureMethod, TypeMappers.NeoValueConverter outputMapper, Method udfMethod, TypeMappers.NeoValueConverter outputMapper,
List<FieldInjections.FieldSetter> fieldSetters ) List<FieldInjections.FieldSetter> fieldSetters )
{ {
super( fieldSetters ); super( fieldSetters );
this.constructor = constructor; this.constructor = constructor;
this.udfMethod = procedureMethod; this.udfMethod = udfMethod;
this.signature = signature; this.signature = signature;
this.valueConverter = outputMapper; this.valueConverter = outputMapper;
} }
Expand Down Expand Up @@ -757,9 +756,7 @@ public Object apply( Context ctx, Object[] input ) throws ProcedureException
inject( ctx, cls ); inject( ctx, cls );


// Call the method // Call the method
Object[] args = args( numberOfDeclaredArguments, cls, input ); Object rs = udfMethod.invoke( cls, input );

Object rs = udfMethod.invokeWithArguments( args );


return valueConverter.toNeoValue( rs ); return valueConverter.toNeoValue( rs );
} }
Expand All @@ -768,12 +765,12 @@ public Object apply( Context ctx, Object[] input ) throws ProcedureException
if ( throwable instanceof Status.HasStatus ) if ( throwable instanceof Status.HasStatus )
{ {
throw new ProcedureException( ((Status.HasStatus) throwable).status(), throwable, throw new ProcedureException( ((Status.HasStatus) throwable).status(), throwable,
throwable.getMessage() ); throwable.getMessage(), throwable );
} }
else else
{ {
throw new ProcedureException( Status.Procedure.ProcedureCallFailed, throwable, throw new ProcedureException( Status.Procedure.ProcedureCallFailed, throwable,
"Failed to invoke function `%s`: %s", signature.name(), "Caused by: " + throwable ); "Failed to invoke function `%s`: %s", signature.name(), "Caused by: " + ExceptionUtils.getRootCause( throwable ) );
} }
} }
} }
Expand Down

0 comments on commit 1fa5463

Please sign in to comment.