/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ignite.internal.util.gridify; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.ignite.IgniteException; import org.apache.ignite.compute.ComputeJobAdapter; import org.apache.ignite.compute.gridify.GridifyArgument; /** * Convenience adapter for custom {@code gridify} jobs. In addition to * functionality provided in {@link org.apache.ignite.compute.ComputeJobAdapter} adapter, this adapter * provides default implementation of {@link #execute()} method, * which reflectively executes grid-enabled method based on information provided * in {@link org.apache.ignite.compute.gridify.GridifyArgument} parameter. * <p> * Note this adapter is only useful when passing {@link org.apache.ignite.compute.gridify.GridifyArgument} to * remote jobs. In many cases, remote jobs will not require {@link org.apache.ignite.compute.gridify.GridifyArgument} * as they will execute their code without reflection, hence the regular * {@link org.apache.ignite.compute.ComputeJobAdapter} should be used. * <p> * See {@link org.apache.ignite.compute.gridify.Gridify} documentation for more information about execution of * {@code gridified} methods. * @see org.apache.ignite.compute.gridify.Gridify */ public class GridifyJobAdapter extends ComputeJobAdapter { /** */ private static final long serialVersionUID = 0L; /** * Initializes job with argument. * * @param arg Job argument. */ public GridifyJobAdapter(GridifyArgument arg) { super(arg); } /** * Provides default implementation for execution of grid-enabled methods. * This method assumes that argument passed in is of {@link GridifyArgument} * type. It attempts to reflectively execute a method based on information * provided in the argument and returns the return value of the method. * <p> * If some exception occurred during execution, then it will be thrown * out of this method. * * @return {@inheritDoc} */ @Override public Object execute() { GridifyArgument arg = argument(0); try { // Get public, package, protected, or private method. Method mtd = arg.getMethodClass().getDeclaredMethod(arg.getMethodName(), arg.getMethodParameterTypes()); // Attempt to soften access control in case we grid-enabling // non-accessible method. Subject to security manager setting. if (!mtd.isAccessible()) try { mtd.setAccessible(true); } catch (SecurityException e) { throw new IgniteException("Got security exception when attempting to soften access control for " + "@Gridify method: " + mtd, e); } Object obj = null; // No need to create an instance for static methods. if (!Modifier.isStatic(mtd.getModifiers())) // Obtain instance to execute method on. obj = arg.getTarget(); return mtd.invoke(obj, arg.getMethodParameters()); } catch (InvocationTargetException e) { if (e.getTargetException() instanceof IgniteException) throw (IgniteException)e.getTargetException(); throw new IgniteException("Failed to invoke a method due to user exception.", e.getTargetException()); } catch (IllegalAccessException e) { throw new IgniteException("Failed to access method for execution.", e); } catch (NoSuchMethodException e) { throw new IgniteException("Failed to find method for execution.", e); } } }