aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/src/main/java/org/apache/spark/launcher/AbstractCommandBuilder.java44
-rw-r--r--launcher/src/main/java/org/apache/spark/launcher/CommandBuilderUtils.java1
-rw-r--r--launcher/src/test/java/org/apache/spark/launcher/SparkSubmitCommandBuilderSuite.java15
3 files changed, 51 insertions, 9 deletions
diff --git a/launcher/src/main/java/org/apache/spark/launcher/AbstractCommandBuilder.java b/launcher/src/main/java/org/apache/spark/launcher/AbstractCommandBuilder.java
index d8279145d8..b8f02b9611 100644
--- a/launcher/src/main/java/org/apache/spark/launcher/AbstractCommandBuilder.java
+++ b/launcher/src/main/java/org/apache/spark/launcher/AbstractCommandBuilder.java
@@ -186,12 +186,24 @@ abstract class AbstractCommandBuilder {
addToClassPath(cp, String.format("%s/core/target/jars/*", sparkHome));
}
- final String assembly = AbstractCommandBuilder.class.getProtectionDomain().getCodeSource().
- getLocation().getPath();
+ // We can't rely on the ENV_SPARK_ASSEMBLY variable to be set. Certain situations, such as
+ // when running unit tests, or user code that embeds Spark and creates a SparkContext
+ // with a local or local-cluster master, will cause this code to be called from an
+ // environment where that env variable is not guaranteed to exist.
+ //
+ // For the testing case, we rely on the test code to set and propagate the test classpath
+ // appropriately.
+ //
+ // For the user code case, we fall back to looking for the Spark assembly under SPARK_HOME.
+ // That duplicates some of the code in the shell scripts that look for the assembly, though.
+ String assembly = getenv(ENV_SPARK_ASSEMBLY);
+ if (assembly == null && isEmpty(getenv("SPARK_TESTING"))) {
+ assembly = findAssembly();
+ }
addToClassPath(cp, assembly);
- // Datanucleus jars must be included on the classpath. Datanucleus jars do not work if only
- // included in the uber jar as plugin.xml metadata is lost. Both sbt and maven will populate
+ // Datanucleus jars must be included on the classpath. Datanucleus jars do not work if only
+ // included in the uber jar as plugin.xml metadata is lost. Both sbt and maven will populate
// "lib_managed/jars/" with the datanucleus jars when Spark is built with Hive
File libdir;
if (new File(sparkHome, "RELEASE").isFile()) {
@@ -299,6 +311,30 @@ abstract class AbstractCommandBuilder {
return firstNonEmpty(childEnv.get(key), System.getenv(key));
}
+ private String findAssembly() {
+ String sparkHome = getSparkHome();
+ File libdir;
+ if (new File(sparkHome, "RELEASE").isFile()) {
+ libdir = new File(sparkHome, "lib");
+ checkState(libdir.isDirectory(), "Library directory '%s' does not exist.",
+ libdir.getAbsolutePath());
+ } else {
+ libdir = new File(sparkHome, String.format("assembly/target/scala-%s", getScalaVersion()));
+ }
+
+ final Pattern re = Pattern.compile("spark-assembly.*hadoop.*\\.jar");
+ FileFilter filter = new FileFilter() {
+ @Override
+ public boolean accept(File file) {
+ return file.isFile() && re.matcher(file.getName()).matches();
+ }
+ };
+ File[] assemblies = libdir.listFiles(filter);
+ checkState(assemblies != null && assemblies.length > 0, "No assemblies found in '%s'.", libdir);
+ checkState(assemblies.length == 1, "Multiple assemblies found in '%s'.", libdir);
+ return assemblies[0].getAbsolutePath();
+ }
+
private String getConfDir() {
String confDir = getenv("SPARK_CONF_DIR");
return confDir != null ? confDir : join(File.separator, getSparkHome(), "conf");
diff --git a/launcher/src/main/java/org/apache/spark/launcher/CommandBuilderUtils.java b/launcher/src/main/java/org/apache/spark/launcher/CommandBuilderUtils.java
index f4ebc25bdd..8028e42ffb 100644
--- a/launcher/src/main/java/org/apache/spark/launcher/CommandBuilderUtils.java
+++ b/launcher/src/main/java/org/apache/spark/launcher/CommandBuilderUtils.java
@@ -30,6 +30,7 @@ class CommandBuilderUtils {
static final String DEFAULT_MEM = "512m";
static final String DEFAULT_PROPERTIES_FILE = "spark-defaults.conf";
static final String ENV_SPARK_HOME = "SPARK_HOME";
+ static final String ENV_SPARK_ASSEMBLY = "_SPARK_ASSEMBLY";
/** Returns whether the given string is null or empty. */
static boolean isEmpty(String s) {
diff --git a/launcher/src/test/java/org/apache/spark/launcher/SparkSubmitCommandBuilderSuite.java b/launcher/src/test/java/org/apache/spark/launcher/SparkSubmitCommandBuilderSuite.java
index 626116a9e7..97043a76cc 100644
--- a/launcher/src/test/java/org/apache/spark/launcher/SparkSubmitCommandBuilderSuite.java
+++ b/launcher/src/test/java/org/apache/spark/launcher/SparkSubmitCommandBuilderSuite.java
@@ -98,7 +98,7 @@ public class SparkSubmitCommandBuilderSuite {
parser.NAME,
"appName");
- List<String> args = new SparkSubmitCommandBuilder(sparkSubmitArgs).buildSparkSubmitArgs();
+ List<String> args = newCommandBuilder(sparkSubmitArgs).buildSparkSubmitArgs();
List<String> expected = Arrays.asList("spark-shell", "--app-arg", "bar", "--app-switch");
assertEquals(expected, args.subList(args.size() - expected.size(), args.size()));
}
@@ -110,7 +110,7 @@ public class SparkSubmitCommandBuilderSuite {
parser.MASTER + "=foo",
parser.DEPLOY_MODE + "=bar");
- List<String> cmd = new SparkSubmitCommandBuilder(sparkSubmitArgs).buildSparkSubmitArgs();
+ List<String> cmd = newCommandBuilder(sparkSubmitArgs).buildSparkSubmitArgs();
assertEquals("org.my.Class", findArgValue(cmd, parser.CLASS));
assertEquals("foo", findArgValue(cmd, parser.MASTER));
assertEquals("bar", findArgValue(cmd, parser.DEPLOY_MODE));
@@ -153,7 +153,7 @@ public class SparkSubmitCommandBuilderSuite {
String deployMode = isDriver ? "client" : "cluster";
SparkSubmitCommandBuilder launcher =
- new SparkSubmitCommandBuilder(Collections.<String>emptyList());
+ newCommandBuilder(Collections.<String>emptyList());
launcher.childEnv.put(CommandBuilderUtils.ENV_SPARK_HOME,
System.getProperty("spark.test.home"));
launcher.master = "yarn";
@@ -273,10 +273,15 @@ public class SparkSubmitCommandBuilderSuite {
return contains(needle, list.split(sep));
}
- private List<String> buildCommand(List<String> args, Map<String, String> env) throws Exception {
+ private SparkSubmitCommandBuilder newCommandBuilder(List<String> args) {
SparkSubmitCommandBuilder builder = new SparkSubmitCommandBuilder(args);
builder.childEnv.put(CommandBuilderUtils.ENV_SPARK_HOME, System.getProperty("spark.test.home"));
- return builder.buildCommand(env);
+ builder.childEnv.put(CommandBuilderUtils.ENV_SPARK_ASSEMBLY, "dummy");
+ return builder;
+ }
+
+ private List<String> buildCommand(List<String> args, Map<String, String> env) throws Exception {
+ return newCommandBuilder(args).buildCommand(env);
}
}