-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-33084][CORE][SQL] Add jar support ivy path #29966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
afaf7bd
51daf9a
3579de0
d6e8caf
169e1f8
0e589ec
b3e3211
9161340
0e3c1ec
300ca56
63e877b
733e62c
b60ba1e
883b9d3
208afc2
ba9ea29
10b3737
7f878c2
d2c1950
2200076
5a9cc30
875d8a7
e921245
614a865
8c5cb7c
f460974
1f7dc01
050c410
ff611a6
03aca3b
653b919
6e48275
bdc5035
9c22882
9c88f8d
8220e5a
49ac62c
b69a62e
273a5ac
ebe1c9c
6034fb2
e22e398
afea73f
13000f2
bce3d40
d53f302
57c351d
8c53b83
4048c5b
aa53482
2ffb431
8c18cdf
6bd41cd
fbc236c
90491d5
75ff3ce
4c44dae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1904,16 +1904,15 @@ class SparkContext(config: SparkConf) extends Logging { | |
| if (path == null || path.isEmpty) { | ||
| logWarning("null or empty path specified as parameter to addJar") | ||
| } else { | ||
| var schema = "" | ||
| val keys = if (path.contains("\\") && Utils.isWindows) { | ||
| val (keys, schema) = if (path.contains("\\") && Utils.isWindows) { | ||
| // For local paths with backslashes on Windows, URI throws an exception | ||
| addLocalJarFile(new File(path)) | ||
| (addLocalJarFile(new File(path)), "local") | ||
| } else { | ||
| val uri = new Path(path).toUri | ||
| // SPARK-17650: Make sure this is a valid URL before adding it to the list of dependencies | ||
| Utils.validateURL(uri) | ||
| schema = uri.getScheme | ||
| schema match { | ||
| val uriSchema = uri.getScheme | ||
AngersZhuuuu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| val jarPaths = uriSchema match { | ||
| // A JAR file which exists only on the driver node | ||
| case null => | ||
| // SPARK-22585 path without schema is not url encoded | ||
|
|
@@ -1928,28 +1927,20 @@ class SparkContext(config: SparkConf) extends Logging { | |
| DependencyUtils.resolveMavenDependencies(URI.create(path)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if two added jars have the same dependency with different versions? e.g.,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| case _ => checkRemoteJarFile(path) | ||
| } | ||
| (jarPaths, uriSchema) | ||
| } | ||
| if (keys.nonEmpty) { | ||
| val timestamp = if (addedOnSubmit) startTime else System.currentTimeMillis | ||
| val (added, existed) = keys.partition(addedJars.putIfAbsent(_, timestamp).isEmpty) | ||
| if (added.nonEmpty) { | ||
| if (schema != "ivy") { | ||
| logInfo(s"Added JAR $path at ${added.mkString(",")} with timestamp $timestamp") | ||
| } else { | ||
| logInfo(s"Added dependency jars of ivy uri $path at ${added.mkString(",")}" + | ||
| s" with timestamp $timestamp") | ||
| } | ||
| val jarMessage = if (schema != "ivy") "JAR" else "dependency jars of ivy uri" | ||
| logInfo(s"Added $jarMessage $path at ${added.mkString(",")} with timestamp $timestamp") | ||
| postEnvironmentUpdate() | ||
| } | ||
| if (existed.nonEmpty) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add tests to check if this warning message is shown only once by using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure |
||
| if (schema != "ivy") { | ||
| logWarning(s"The jar $path has been added already. Overwriting of added jars " + | ||
| "is not supported in the current version.") | ||
| } else { | ||
| logWarning(s"The dependency jars of ivy URI with $path at" + | ||
| s" ${existed.mkString(",")} has been added already." + | ||
| s" Overwriting of added jars is not supported in the current version.") | ||
| } | ||
| val jarMessage = if (schema != "ivy") "JAR" else "dependency jars of ivy uri" | ||
| logInfo(s"The $jarMessage $path at ${existed.mkString(",")} has been added already." + | ||
| s" Overwriting of added jar is not supported in the current version.") | ||
AngersZhuuuu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,7 @@ | |
| package org.apache.spark.util | ||
|
|
||
| import java.io.File | ||
| import java.net.{URI, URISyntaxException} | ||
| import java.net.URI | ||
|
|
||
| import org.apache.commons.lang3.StringUtils | ||
| import org.apache.hadoop.conf.Configuration | ||
|
|
@@ -48,6 +48,10 @@ private[spark] object DependencyUtils extends Logging { | |
| IvyProperties(packagesExclusions, packages, repositories, ivyRepoPath, ivySettingsPath) | ||
| } | ||
|
|
||
AngersZhuuuu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private def checkInvalidQueryString(tokens: Array[String]): Boolean = { | ||
| tokens.length != 2 || StringUtils.isBlank(tokens(0)) || StringUtils.isBlank(tokens(1)) | ||
| } | ||
|
|
||
| /** | ||
| * Parse URI query string's parameter value of `transitive` and `exclude`. | ||
| * Other invalid parameters will be ignored. | ||
|
|
@@ -71,13 +75,13 @@ private[spark] object DependencyUtils extends Logging { | |
| (false, "") | ||
| } else { | ||
| val mapTokens = uriQuery.split("&").map(_.split("=")) | ||
| if (mapTokens.exists(token => | ||
| token.length != 2 || StringUtils.isBlank(token(0)) || StringUtils.isBlank(token(1)))) { | ||
| throw new URISyntaxException(uri.toString, s"Invalid query string: $uriQuery") | ||
| if (mapTokens.exists(checkInvalidQueryString)) { | ||
| throw new IllegalArgumentException( | ||
| s"Invalid query string in ivy uri ${uri.toString}: $uriQuery") | ||
| } | ||
| val groupedParams = mapTokens.map(kv => (kv(0), kv(1))).groupBy(_._1) | ||
| // Parse transitive parameters (e.g., transitive=true) in an ivy URL, default value is false | ||
| var transitive: Boolean = false | ||
| var transitive = false | ||
|
||
| groupedParams.get("transitive").foreach { params => | ||
| if (params.length > 1) { | ||
| logWarning("It's best to specify `transitive` parameter in ivy URL query only once." + | ||
|
|
@@ -94,27 +98,20 @@ private[spark] object DependencyUtils extends Logging { | |
| val exclusionList = groupedParams.get("exclude").map { params => | ||
| params.map(_._2).flatMap { excludeString => | ||
| val excludes = excludeString.split(",") | ||
| if (excludes.map(_.split(":")).exists(token => | ||
| token.length != 2 || StringUtils.isBlank(token(0)) || StringUtils.isBlank(token(1)))) { | ||
| throw new URISyntaxException(uri.toString, "Invalid exclude string: " + | ||
| "expected 'org:module,org:module,..', found " + excludeString) | ||
| if (excludes.map(_.split(":")).exists(checkInvalidQueryString)) { | ||
| throw new IllegalArgumentException( | ||
| s"Invalid exclude string in ivy uri ${uri.toString}:" + | ||
| s" expected 'org:module,org:module,..', found " + excludeString) | ||
AngersZhuuuu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| excludes | ||
| }.mkString(",") | ||
| }.getOrElse("") | ||
|
|
||
| val invalidParams = groupedParams | ||
| .filter(entry => !Seq("transitive", "exclude").contains(entry._1)) | ||
| .keys.toArray.sorted | ||
| val validParams = Set("transitive", "exclude") | ||
| val invalidParams = groupedParams.keys.filterNot(validParams.contains).toSeq.sorted | ||
AngersZhuuuu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (invalidParams.nonEmpty) { | ||
| logWarning( | ||
| s"Invalid parameters `${invalidParams.mkString(",")}` found in URI query `$uriQuery`.") | ||
| } | ||
|
|
||
| groupedParams.foreach { case (key: String, values: Array[(String, String)]) => | ||
| if (key != "transitive" || key != "exclude") { | ||
| logWarning("Invalid parameter") | ||
| } | ||
| logWarning(s"Invalid parameters `${invalidParams.mkString(",")}` found " + | ||
| s"in ivy URI query `$uriQuery`.") | ||
| } | ||
|
|
||
| (transitive, exclusionList) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if an invalid param is given in hive, e.g.,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like we should at least warn on invalid param? |
||
|
|
@@ -137,32 +134,29 @@ private[spark] object DependencyUtils extends Logging { | |
| * @return Comma separated string list of jars downloaded. | ||
| */ | ||
| def resolveMavenDependencies(uri: URI): Seq[String] = { | ||
| try { | ||
| val ivyProperties = DependencyUtils.getIvyProperties() | ||
| val authority = uri.getAuthority | ||
| if (authority == null) { | ||
| throw new URISyntaxException( | ||
| uri.toString, "Invalid url: Expected 'org:module:version', found null") | ||
| } | ||
| if (authority.split(":").length != 3) { | ||
| throw new URISyntaxException( | ||
| uri.toString, "Invalid url: Expected 'org:module:version', found " + authority) | ||
| } | ||
| val ivyProperties = DependencyUtils.getIvyProperties() | ||
| val authority = uri.getAuthority | ||
| if (authority == null) { | ||
| throw new IllegalArgumentException( | ||
| s"Invalid ivy url authority in uri ${uri.toString}:" + | ||
| s" Expected 'org:module:version', found null.") | ||
AngersZhuuuu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| if (authority.split(":").length != 3) { | ||
| throw new IllegalArgumentException( | ||
| s"Invalid ivy uri authority in uri ${uri.toString}:" + | ||
AngersZhuuuu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| s" Expected 'org:module:version', found $authority.") | ||
| } | ||
|
|
||
| val (transitive, exclusionList) = parseQueryParams(uri) | ||
| val (transitive, exclusionList) = parseQueryParams(uri) | ||
|
|
||
| resolveMavenDependencies( | ||
| transitive, | ||
| exclusionList, | ||
| authority, | ||
| ivyProperties.repositories, | ||
| ivyProperties.ivyRepoPath, | ||
| Option(ivyProperties.ivySettingsPath) | ||
| ).split(",") | ||
| } catch { | ||
| case e: URISyntaxException => | ||
| throw new IllegalArgumentException(e.getMessage) | ||
| } | ||
| resolveMavenDependencies( | ||
| transitive, | ||
| exclusionList, | ||
| authority, | ||
| ivyProperties.repositories, | ||
| ivyProperties.ivyRepoPath, | ||
| Option(ivyProperties.ivySettingsPath) | ||
| ).split(",") | ||
| } | ||
|
|
||
| def resolveMavenDependencies( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.