Commit 2c2e118
committed
[SPARK-1522]: YARN ClientBase throws a NPE if there is no YARN Application specific CP
The current implementation of ClientBase.getDefaultYarnApplicationClasspath inspects
the MRJobConfig class for the field DEFAULT_YARN_APPLICATION_CLASSPATH when it should
be really looking into YarnConfiguration. If the Application Configuration has no
yarn.application.classpath defined a NPE exception will be thrown.
Public API Changes
===========================
* YARN ClientBase getDefault*ApplicationClasspath returns Option[Seq[String]]
This commit depicts how the `ClientBase` API could change the
`getDefaultYarnApplicationClasspath` and `getDefaultMRApplicationClasspath`
to return a `Option[Seq[String]]` while recovering from `NoSuchFieldException`.
Both methods that return the default application's *classpath*, for both *YARN*
as well as *Map Reduce (MR)*, use reflection and per the Java API
documentation they can throw the following exceptions:
* Class:getField(String name):
* NoSuchFieldException - if a field with the specified name is not found.
* NullPointerException - if name is null
* SecurityException - If a security manager, s, is present and any of
the following conditions is met:
1. Invocation of s.checkMemberAccess(this, Member.PUBLIC) denies
access to the field.
2. The caller's class loader is not the same as or an ancestor of
the class loader for the current class and invocation of
`s.checkPackageAccess()` denies access to the package of this class.
* Field:Object get(Object obj):
* IllegalAccessException - if this Field object is enforcing Java language access
control and the underlying field is inaccessible.
* IllegalArgumentException - if the specified object is not an instance of the class
or interface declaring the underlying field (or a subclass or implementor thereof).
* NullPointerException - if the specified object is null and the field
is an instance field.
* ExceptionInInitializerError - if the initialization provoked
by this method fails.
**NOTE**: The above is based on the *Java API for JDK 1.7*
An interesting thing to notice is that the official JDK doesn't mention
the occurrence of the `NoSuchFieldError`. This is completely acceptable
per the JDK spec. The reason is that it is an *Error* and as
described by the Java Language Specification and depicted in
the *Error Class* documentation.
An `Error` "indicates serious problems that a reasonable
application should not try to catch."
While
An `Exception` "indicates conditions that a reasonable
application might want to catch."
If we actually dig deeper according to the *JVM SE7 Specification*
"While Loading, Linking, and Initializing, if an error occurs during resolution
of a symbolic reference, then an instance of
IncompatibleClassChangeError (or a subclass) must be thrown..."
"If an attempt by the Java Virtual Machine to resolve a symbolic reference fails
because an error is thrown that is an instance of LinkageError (or a subclass),
then subsequent attempts to resolve the reference always fail with the same error
that was thrown as a result of the initial resolution attempt."
Now `NoSuchFieldError` extends `LinkageError` which in turn is a `IncompatibleClassChangeError`
and according to its documentation, the *LinkageError Class*,
"indicates that a class has some dependency on another class;
however, the latter class has incompatibly changed after the
compilation of the former class."
Why all these is important and how it relates with a couple of lines of
code?
Well, the original approach catches the two most probable problems
you might encounter if you access, using reflection, a field that you
are almost sure that if it exist it will be of _public_ access but you
are not sure it will always be there. Interesting enough the original
implementation addresses one of the _exceptions_ as well as a potential
_linkage error_ but as mentioned neglects a documented _security exception_,
probably due its unlikeliness to occur.
Fact is that if an error _bubbles_ up the Spark YARN Client doesn't handle it
will terminate, in a probably obscure fashion. The current call stack is
as follows.
Client >> run >> runApp >> ClientBase.setupLaunchEnv >> populateClasspath
In my opinion it is questionable to let an exception escape of this context, the _ClientBase Object_.
In my opinion such _ClientBase Object_ should fail gracefully by handling the potential
_exceptions_ and _linkage error_ while providing enough logging
to let a user know and identify what happened. Yet again, in my opinion
the implementation in this commit handles it in a better, more
resilient, manner than the previous implementation while adding logging
that will help clarify the issues in case of an _exception_.
Additional Changes include:
===========================
* Test Suite for ClientBase added
* Coding Style:
* [Spark Style Guidelines](https://cwiki.apache.org/confluence/display/SPARK/Spark+Code+Style+Guide)
* [Scala Official Style Guidelines](http://docs.scala-lang.org/style/)
* [Scalariform](https://github.com/mdr/scalariform)
* Code refactoring and cleanup per review by andrewor14
Ref.
"JVM SE7 Specification" http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4
"Java API for JDK 1.7" http://docs.oracle.com/javase/7/docs/api/
[ticket: SPARK-1522] : https://issues.apache.org/jira/browse/SPARK-1522
Author : berngp
Reviewer : andrewor14, tgravescs
Testing : ?1 parent 8d85359 commit 2c2e118
File tree
2 files changed
+167
-34
lines changed- yarn/common/src
- main/scala/org/apache/spark/deploy/yarn
- test/scala/org/apache/spark/deploy/yarn
2 files changed
+167
-34
lines changedLines changed: 55 additions & 34 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
378 | 379 | | |
379 | 380 | | |
380 | 381 | | |
381 | | - | |
| 382 | + | |
382 | 383 | | |
383 | 384 | | |
384 | 385 | | |
| |||
388 | 389 | | |
389 | 390 | | |
390 | 391 | | |
391 | | - | |
392 | | - | |
393 | | - | |
394 | | - | |
395 | | - | |
396 | | - | |
397 | | - | |
398 | | - | |
399 | | - | |
400 | | - | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
401 | 400 | | |
| 401 | + | |
| 402 | + | |
402 | 403 | | |
403 | | - | |
404 | | - | |
405 | | - | |
406 | | - | |
407 | | - | |
408 | | - | |
409 | | - | |
410 | | - | |
411 | | - | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
412 | 408 | | |
413 | 409 | | |
414 | | - | |
415 | | - | |
416 | | - | |
417 | | - | |
418 | | - | |
419 | | - | |
420 | | - | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
421 | 423 | | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
422 | 433 | | |
423 | 434 | | |
424 | 435 | | |
425 | 436 | | |
426 | 437 | | |
427 | 438 | | |
428 | 439 | | |
429 | | - | |
430 | | - | |
| 440 | + | |
| 441 | + | |
431 | 442 | | |
432 | | - | |
433 | | - | |
| 443 | + | |
| 444 | + | |
434 | 445 | | |
435 | 446 | | |
436 | 447 | | |
437 | | - | |
438 | | - | |
439 | | - | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
440 | 451 | | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
441 | 461 | | |
442 | 462 | | |
| 463 | + | |
443 | 464 | | |
444 | 465 | | |
445 | 466 | | |
| |||
Lines changed: 112 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
0 commit comments