package org.apache.blur.spark.util;
/**
* 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.
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.spark.SparkConf;
import com.google.common.base.Splitter;
public class JavaSparkUtil {
private static final String DOT = ".";
private static final String TMP_SPARK_JOB = "tmp-spark-job_";
private static final String JAR = ".jar";
private static final String PATH_SEPARATOR = "path.separator";
private static final String JAVA_CLASS_PATH = "java.class.path";
private static final String SEP = "/";
public static void packProjectJars(SparkConf conf) throws IOException {
String classPath = System.getProperty(JAVA_CLASS_PATH);
String pathSeparator = System.getProperty(PATH_SEPARATOR);
Splitter splitter = Splitter.on(pathSeparator);
Iterable<String> split = splitter.split(classPath);
List<String> list = toList(split);
List<String> classPathThatNeedsToBeIncluded = removeSparkLibs(list);
List<String> jars = new ArrayList<String>();
for (String s : classPathThatNeedsToBeIncluded) {
if (isJarFile(s)) {
jars.add(s);
} else {
jars.add(createJar(s));
}
}
conf.setJars(jars.toArray(new String[jars.size()]));
}
private static String createJar(String s) throws IOException {
File sourceFile = new File(s);
if (sourceFile.isDirectory()) {
File file = File.createTempFile(TMP_SPARK_JOB, JAR);
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
JarOutputStream jarOut = new JarOutputStream(outputStream);
for (File f : sourceFile.listFiles()) {
pack(sourceFile, f, jarOut);
}
jarOut.close();
file.deleteOnExit();
return file.getAbsolutePath();
}
throw new RuntimeException("File [" + s + "] is not a directory.");
}
private static void pack(File rootPath, File source, JarOutputStream target) throws IOException {
String name = getName(rootPath, source);
if (source.isDirectory()) {
if (!SEP.equals(name)) {
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
target.closeEntry();
}
for (File f : source.listFiles()) {
pack(rootPath, f, target);
}
} else {
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
IOUtils.copy(in, target);
in.close();
target.closeEntry();
}
}
private static String getName(File rootPath, File source) {
String rootStr = rootPath.toURI().toString();
String sourceStr = source.toURI().toString();
if (sourceStr.startsWith(rootStr)) {
String result = sourceStr.substring(rootStr.length());
if (source.isDirectory() && !result.endsWith(SEP)) {
result += SEP;
}
return result;
} else {
throw new RuntimeException("Not sure what happened.");
}
}
private static boolean isJarFile(String s) {
if (s.endsWith(JAR) || s.endsWith(".zip")) {
return true;
}
return false;
}
private static List<String> removeSparkLibs(List<String> list) {
String sparkJar = findSparkJar(list);
String sparkLib = sparkJar.substring(0, sparkJar.lastIndexOf(SEP) + 1);
List<String> result = new ArrayList<String>();
for (String s : list) {
if (!s.startsWith(sparkLib)) {
result.add(s);
}
}
return result;
}
private static String findSparkJar(List<String> list) {
String name = SparkConf.class.getName();
String resourceName = SEP + name.replace(DOT, SEP) + ".class";
URL url = SparkConf.class.getResource(resourceName);
String urlStr = url.toString();
urlStr = urlStr.substring(0, urlStr.indexOf('!'));
urlStr = urlStr.substring(urlStr.lastIndexOf(':') + 1);
return urlStr;
}
private static List<String> toList(Iterable<String> split) {
List<String> list = new ArrayList<String>();
for (String s : split) {
list.add(s);
}
return list;
}
}