All Downloads are FREE. Search and download functionalities are using the official Maven repository.

co.cask.hydrator.plugin.spark.dynamic.SparkCompilers Maven / Gradle / Ivy

There is a newer version: 2.1.2
Show newest version
/*
 * Copyright © 2017 Cask Data, Inc.
 *
 * Licensed 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 co.cask.hydrator.plugin.spark.dynamic;

import co.cask.cdap.api.spark.dynamic.SparkInterpreter;
import scala.Function0;
import scala.Option$;
import scala.reflect.io.VirtualDirectory;
import scala.runtime.AbstractFunction0;
import scala.runtime.BoxedUnit;
import scala.tools.nsc.Settings;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.annotation.Nullable;

/**
 * Helper class for Spark compilation. We don't need this class when CDAP-11812 is resolved.
 */
public final class SparkCompilers {

  @Nullable
  public static SparkInterpreter createInterpreter() {
    try {
      ClassLoader classLoader = SparkInterpreter.class.getClassLoader();
      Settings settings = (Settings) classLoader
        .loadClass("co.cask.cdap.app.runtime.spark.dynamic.AbstractSparkCompiler")
        .getDeclaredMethod("setClassPath", Settings.class)
        .invoke(null, new Settings());

      Class interpreterClass = classLoader
        .loadClass("co.cask.cdap.app.runtime.spark.dynamic.DefaultSparkInterpreter");

      // There should be a constructor
      Constructor[] constructors = interpreterClass.getDeclaredConstructors();
      if (constructors.length != 1) {
        return null;
      }
      Constructor constructor = constructors[0];

      // Create a empty URLAdder implementation using proxy, because that class is not available via cdap api
      InvocationHandler handler = new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          // no-op
          return null;
        }
      };
      Class urlAdderClass = classLoader.loadClass("co.cask.cdap.app.runtime.spark.dynamic.URLAdder");
      Object urlAdder = Proxy.newProxyInstance(classLoader, new Class[]{urlAdderClass}, handler);
      Function0 onCloseFunc = new AbstractFunction0() {
        @Override
        public BoxedUnit apply() {
          return BoxedUnit.UNIT;
        }
      };

      // For Spark 1, the constructor has 4 parameters. For Spark 2, it has 3 parameters
      SparkInterpreter sparkInterpreter = null;
      if (constructor.getParameterTypes().length == 4) {
        // Spark 1
        VirtualDirectory virtualDirectory = new VirtualDirectory("memory", Option$.MODULE$.empty());
        sparkInterpreter = (SparkInterpreter) constructor.newInstance(settings, virtualDirectory,
                                                                      urlAdder, onCloseFunc);

      } else if (constructor.getParameterTypes().length == 3) {
        // spark 2
        sparkInterpreter = (SparkInterpreter) constructor.newInstance(settings, urlAdder, onCloseFunc);
      }

      return sparkInterpreter;
    } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException
                                    | IllegalAccessException | InstantiationException e) {
      return null;
    }
  }

  private SparkCompilers() {
    // no-op
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy