You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by rk...@apache.org on 2014/04/24 21:08:48 UTC
git commit: OOZIE-1794 java-opts and java-opt in the Java action
don't always work properly in YARN (rkanter)
Repository: oozie
Updated Branches:
refs/heads/master eed805ec3 -> d77b0d8a7
OOZIE-1794 java-opts and java-opt in the Java action don't always work properly in YARN (rkanter)
Project: http://git-wip-us.apache.org/repos/asf/oozie/repo
Commit: http://git-wip-us.apache.org/repos/asf/oozie/commit/d77b0d8a
Tree: http://git-wip-us.apache.org/repos/asf/oozie/tree/d77b0d8a
Diff: http://git-wip-us.apache.org/repos/asf/oozie/diff/d77b0d8a
Branch: refs/heads/master
Commit: d77b0d8a768508bd165763e7b132fa4cff5fe260
Parents: eed805e
Author: Robert Kanter <rk...@cloudera.com>
Authored: Thu Apr 24 12:05:05 2014 -0700
Committer: Robert Kanter <rk...@cloudera.com>
Committed: Thu Apr 24 12:05:05 2014 -0700
----------------------------------------------------------------------
.../oozie/action/hadoop/JavaActionExecutor.java | 38 +++---
.../action/hadoop/TestJavaActionExecutor.java | 121 +++++++++++++++++--
.../src/site/twiki/WorkflowFunctionalSpec.twiki | 18 ++-
3 files changed, 140 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/oozie/blob/d77b0d8a/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java b/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java
index 6fcdf2a..59ad143 100644
--- a/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java
+++ b/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java
@@ -280,13 +280,10 @@ public class JavaActionExecutor extends ActionExecutor {
}
launcherConf.setInt(YARN_AM_RESOURCE_MB, memoryMB);
- // child.java.opts
- String launcherMapOpts = launcherConf.get(HADOOP_MAP_JAVA_OPTS);
- if (launcherMapOpts == null) {
- launcherMapOpts = launcherConf.get(HADOOP_CHILD_JAVA_OPTS);
- }
+ // We already made mapred.child.java.opts and mapreduce.map.java.opts equal, so just start with one of them
+ String launcherMapOpts = launcherConf.get(HADOOP_MAP_JAVA_OPTS, "");
String amChildOpts = launcherConf.get(YARN_AM_COMMAND_OPTS);
- StringBuffer optsStr = new StringBuffer();
+ StringBuilder optsStr = new StringBuilder();
int heapSizeForMap = extractHeapSizeMB(launcherMapOpts);
int heapSizeForAm = extractHeapSizeMB(amChildOpts);
int heapSize = Math.max(heapSizeForMap, heapSizeForAm) + YARN_MEMORY_MB_MIN;
@@ -297,16 +294,12 @@ public class JavaActionExecutor extends ActionExecutor {
if (amChildOpts != null) {
optsStr.append(amChildOpts);
}
- if (launcherMapOpts != null) {
- optsStr.append(" ");
- optsStr.append(launcherMapOpts);
- }
+ optsStr.append(" ").append(launcherMapOpts.trim());
if (heapSize > 0) {
// append calculated total heap size to the end
- optsStr.append(" ");
- optsStr.append("-Xmx" + heapSize + "m");
+ optsStr.append(" ").append("-Xmx").append(heapSize).append("m");
}
- launcherConf.set(YARN_AM_COMMAND_OPTS, optsStr.toString());
+ launcherConf.set(YARN_AM_COMMAND_OPTS, optsStr.toString().trim());
// child.env
String launcherMapEnv = launcherConf.get(HADOOP_MAP_JAVA_ENV);
@@ -759,21 +752,22 @@ public class JavaActionExecutor extends ActionExecutor {
}
LauncherMapperHelper.setupMainArguments(launcherJobConf, args);
+ // Make mapred.child.java.opts and mapreduce.map.java.opts equal, but give values from the latter priority; also append
+ // <java-opt> and <java-opts> and give those highest priority
+ StringBuilder opts = new StringBuilder(launcherJobConf.get(HADOOP_CHILD_JAVA_OPTS, ""));
+ if (launcherJobConf.get(HADOOP_MAP_JAVA_OPTS) != null) {
+ opts.append(" ").append(launcherJobConf.get(HADOOP_MAP_JAVA_OPTS));
+ }
List<Element> javaopts = actionXml.getChildren("java-opt", ns);
for (Element opt: javaopts) {
- String opts = launcherJobConf.get("mapred.child.java.opts", "");
- opts = opts + " " + opt.getTextTrim();
- opts = opts.trim();
- launcherJobConf.set("mapred.child.java.opts", opts);
+ opts.append(" ").append(opt.getTextTrim());
}
-
Element opt = actionXml.getChild("java-opts", ns);
if (opt != null) {
- String opts = launcherJobConf.get("mapred.child.java.opts", "");
- opts = opts + " " + opt.getTextTrim();
- opts = opts.trim();
- launcherJobConf.set("mapred.child.java.opts", opts);
+ opts.append(" ").append(opt.getTextTrim());
}
+ launcherJobConf.set(HADOOP_CHILD_JAVA_OPTS, opts.toString().trim());
+ launcherJobConf.set(HADOOP_MAP_JAVA_OPTS, opts.toString().trim());
// setting for uber mode
if (launcherJobConf.getBoolean(HADOOP_YARN_UBER_MODE, false)) {
http://git-wip-us.apache.org/repos/asf/oozie/blob/d77b0d8a/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java b/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java
index 62c57a8..390ad3f 100644
--- a/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java
+++ b/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java
@@ -242,6 +242,7 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
assertEquals("MAIN-CLASS", actionConf.get("oozie.action.java.main", "null"));
assertEquals("org.apache.oozie.action.hadoop.JavaMain", ae.getLauncherMain(conf, actionXml));
assertTrue(conf.get("mapred.child.java.opts").contains("JAVA-OPTS"));
+ assertTrue(conf.get("mapreduce.map.java.opts").contains("JAVA-OPTS"));
assertEquals(Arrays.asList("A1", "A2"), Arrays.asList(LauncherMapper.getMainArguments(conf)));
assertTrue(getFileSystem().exists(new Path(context.getActionDir(), LauncherMapper.ACTION_CONF_XML)));
@@ -1061,8 +1062,8 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
Configuration conf = ae.createLauncherConf(getFileSystem(), context, action, actionXmlconf, actionConf);
- assertTrue(conf.get("mapred.child.java.opts").contains("JAVA-OPT1"));
- assertTrue(conf.get("mapred.child.java.opts").contains("JAVA-OPT2"));
+ assertEquals("-Xmx200m JAVA-OPT1 JAVA-OPT2", conf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx200m JAVA-OPT1 JAVA-OPT2", conf.get("mapreduce.map.java.opts"));
actionXml = "<java>" + "<job-tracker>" + getJobTrackerUri() + "</job-tracker>" + "<name-node>"
+ getNameNodeUri() + "</name-node>" + "<job-xml>job.xml</job-xml>" + "<job-xml>job2.xml</job-xml>"
@@ -1086,8 +1087,90 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
conf = ae.createLauncherConf(getFileSystem(), context, action, actionXmlconf, actionConf);
- assertTrue(conf.get("mapred.child.java.opts").contains("JAVA-OPT1"));
- assertTrue(conf.get("mapred.child.java.opts").contains("JAVA-OPT2"));
+ assertEquals("-Xmx200m JAVA-OPT1 JAVA-OPT2", conf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx200m JAVA-OPT1 JAVA-OPT2", conf.get("mapreduce.map.java.opts"));
+
+ actionXml = "<java>" + "<job-tracker>" + getJobTrackerUri() + "</job-tracker>" + "<name-node>"
+ + getNameNodeUri() + "</name-node>" + "<job-xml>job.xml</job-xml>" + "<job-xml>job2.xml</job-xml>"
+ + "<configuration>" + "<property><name>oozie.launcher.a</name><value>LA</value></property>"
+ + "<property><name>a</name><value>AA</value></property>"
+ + "<property><name>b</name><value>BB</value></property>"
+ + "<property><name>oozie.launcher.mapred.child.java.opts</name><value>JAVA-OPT3</value></property>"
+ + "</configuration>"
+ + "<main-class>MAIN-CLASS</main-class>" + "<java-opt>JAVA-OPT1</java-opt>"
+ + "<java-opt>JAVA-OPT2</java-opt>" + "<arg>A1</arg>" + "<arg>A2</arg>" + "<file>f.jar</file>"
+ + "<archive>a.tar</archive>" + "</java>";
+
+ wfBean = addRecordToWfJobTable("test1", actionXml);
+ action = (WorkflowActionBean) wfBean.getActions().get(0);
+ action.setType(ae.getType());
+ action.setConf(actionXml);
+
+ context = new Context(wfBean, action);
+
+ actionXmlconf = XmlUtils.parseXml(action.getConf());
+
+ actionConf = ae.createBaseHadoopConf(context, actionXmlconf);
+
+ conf = ae.createLauncherConf(getFileSystem(), context, action, actionXmlconf, actionConf);
+
+ assertEquals("JAVA-OPT3 JAVA-OPT1 JAVA-OPT2", conf.get("mapred.child.java.opts"));
+ assertEquals("JAVA-OPT3 JAVA-OPT1 JAVA-OPT2", conf.get("mapreduce.map.java.opts"));
+
+ actionXml = "<java>" + "<job-tracker>" + getJobTrackerUri() + "</job-tracker>" + "<name-node>"
+ + getNameNodeUri() + "</name-node>" + "<job-xml>job.xml</job-xml>" + "<job-xml>job2.xml</job-xml>"
+ + "<configuration>" + "<property><name>oozie.launcher.a</name><value>LA</value></property>"
+ + "<property><name>a</name><value>AA</value></property>"
+ + "<property><name>b</name><value>BB</value></property>"
+ + "<property><name>oozie.launcher.mapreduce.map.java.opts</name><value>JAVA-OPT3</value></property>"
+ + "</configuration>"
+ + "<main-class>MAIN-CLASS</main-class>" + "<java-opt>JAVA-OPT1</java-opt>"
+ + "<java-opt>JAVA-OPT2</java-opt>" + "<arg>A1</arg>" + "<arg>A2</arg>" + "<file>f.jar</file>"
+ + "<archive>a.tar</archive>" + "</java>";
+
+ wfBean = addRecordToWfJobTable("test1", actionXml);
+ action = (WorkflowActionBean) wfBean.getActions().get(0);
+ action.setType(ae.getType());
+ action.setConf(actionXml);
+
+ context = new Context(wfBean, action);
+
+ actionXmlconf = XmlUtils.parseXml(action.getConf());
+
+ actionConf = ae.createBaseHadoopConf(context, actionXmlconf);
+
+ conf = ae.createLauncherConf(getFileSystem(), context, action, actionXmlconf, actionConf);
+
+ assertEquals("-Xmx200m JAVA-OPT3 JAVA-OPT1 JAVA-OPT2", conf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx200m JAVA-OPT3 JAVA-OPT1 JAVA-OPT2", conf.get("mapreduce.map.java.opts"));
+
+ actionXml = "<java>" + "<job-tracker>" + getJobTrackerUri() + "</job-tracker>" + "<name-node>"
+ + getNameNodeUri() + "</name-node>" + "<job-xml>job.xml</job-xml>" + "<job-xml>job2.xml</job-xml>"
+ + "<configuration>" + "<property><name>oozie.launcher.a</name><value>LA</value></property>"
+ + "<property><name>a</name><value>AA</value></property>"
+ + "<property><name>b</name><value>BB</value></property>"
+ + "<property><name>oozie.launcher.mapred.child.java.opts</name><value>JAVA-OPT3</value></property>"
+ + "<property><name>oozie.launcher.mapreduce.map.java.opts</name><value>JAVA-OPT4</value></property>"
+ + "</configuration>"
+ + "<main-class>MAIN-CLASS</main-class>" + "<java-opt>JAVA-OPT1</java-opt>"
+ + "<java-opt>JAVA-OPT2</java-opt>" + "<arg>A1</arg>" + "<arg>A2</arg>" + "<file>f.jar</file>"
+ + "<archive>a.tar</archive>" + "</java>";
+
+ wfBean = addRecordToWfJobTable("test1", actionXml);
+ action = (WorkflowActionBean) wfBean.getActions().get(0);
+ action.setType(ae.getType());
+ action.setConf(actionXml);
+
+ context = new Context(wfBean, action);
+
+ actionXmlconf = XmlUtils.parseXml(action.getConf());
+
+ actionConf = ae.createBaseHadoopConf(context, actionXmlconf);
+
+ conf = ae.createLauncherConf(getFileSystem(), context, action, actionXmlconf, actionConf);
+
+ assertEquals("JAVA-OPT3 JAVA-OPT4 JAVA-OPT1 JAVA-OPT2", conf.get("mapred.child.java.opts"));
+ assertEquals("JAVA-OPT3 JAVA-OPT4 JAVA-OPT1 JAVA-OPT2", conf.get("mapreduce.map.java.opts"));
}
public void testActionLibsPath() throws Exception {
@@ -1624,6 +1707,8 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
assertEquals("2560", launcherConf.get(JavaActionExecutor.YARN_AM_RESOURCE_MB));
// heap size in child.opts (2048 + 512)
int heapSize = ae.extractHeapSizeMB(launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS));
+ assertEquals("-Xmx2048m -Djava.net.preferIPv4Stack=true", launcherConf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx2048m -Djava.net.preferIPv4Stack=true", launcherConf.get("mapreduce.map.java.opts"));
// There's an extra parameter (-Xmx1024m) in here when using YARN that's not here when using MR1
if (createJobConf().get("yarn.resourcemanager.address") != null) {
assertEquals("-Xmx1024m -Xmx2048m -Djava.net.preferIPv4Stack=true -Xmx2560m",
@@ -1633,6 +1718,7 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
assertEquals("-Xmx2048m -Djava.net.preferIPv4Stack=true -Xmx2560m",
launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS).trim());
}
+ assertEquals(2560, heapSize);
// env
assertEquals("A=foo", launcherConf.get(JavaActionExecutor.YARN_AM_ENV));
@@ -1664,7 +1750,9 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
// heap size (2560 + 512)
heapSize = ae.extractHeapSizeMB(launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS));
- assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx2560m -XX:NewRatio=8 -Xmx3072m",
+ assertEquals("-Xmx1536m -Xmx2560m -XX:NewRatio=8", launcherConf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx1536m -Xmx2560m -XX:NewRatio=8", launcherConf.get("mapreduce.map.java.opts"));
+ assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx1536m -Xmx2560m -XX:NewRatio=8 -Xmx3072m",
launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS).trim());
assertEquals(3072, heapSize);
@@ -1700,8 +1788,11 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
// heap size (limit to 3584)
heapSize = ae.extractHeapSizeMB(launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS));
- assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx4000m -XX:NewRatio=8 -Xmx3584m",
+ assertEquals("-Xmx1536m -Xmx4000m -XX:NewRatio=8", launcherConf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx1536m -Xmx4000m -XX:NewRatio=8", launcherConf.get("mapreduce.map.java.opts"));
+ assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx1536m -Xmx4000m -XX:NewRatio=8 -Xmx3584m",
launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS).trim());
+ assertEquals(3584, heapSize);
// env (equqls to mapreduce.map.env + am.env)
assertEquals("A=foo,B=bar", launcherConf.get(JavaActionExecutor.YARN_AM_ENV));
@@ -1721,7 +1812,7 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
+ "<configuration>"
+ "<property><name>oozie.launcher.yarn.app.mapreduce.am.command-opts</name>"
+ "<value>-Xmx1024m -Djava.net.preferIPv4Stack=true </value></property>"
- + "<property><name>oozie.launcher.mapred.child.java.opts</name><value>-Xmx1536m</value></property>"
+ + "<property><name>oozie.launcher.mapreduce.map.java.opts</name><value>-Xmx1536m</value></property>"
+ "</configuration>" + "<main-class>MAIN-CLASS</main-class>"
+ "<java-opt>-Xmx2048m</java-opt>"
+ "<java-opt>-Dkey1=val1</java-opt>"
@@ -1741,7 +1832,9 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
// heap size (2048 + 512)
int heapSize = ae.extractHeapSizeMB(launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS));
- assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx1536m -Xmx2048m -Dkey1=val1 -Dkey2=val2 -Xmx2560m",
+ assertEquals("-Xmx200m -Xmx1536m -Xmx2048m -Dkey1=val1 -Dkey2=val2", launcherConf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx200m -Xmx1536m -Xmx2048m -Dkey1=val1 -Dkey2=val2", launcherConf.get("mapreduce.map.java.opts"));
+ assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx200m -Xmx1536m -Xmx2048m -Dkey1=val1 -Dkey2=val2 -Xmx2560m",
launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS).trim());
assertEquals(2560, heapSize);
@@ -1756,7 +1849,7 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
+ "<configuration>"
+ "<property><name>oozie.launcher.yarn.app.mapreduce.am.command-opts</name>"
+ "<value>-Xmx1024m -Djava.net.preferIPv4Stack=true </value></property>"
- + "<property><name>oozie.launcher.mapred.child.java.opts</name><value>-Xmx1536m</value></property>"
+ + "<property><name>oozie.launcher.mapreduce.map.java.opts</name><value>-Xmx1536m</value></property>"
+ "</configuration>" + "<main-class>MAIN-CLASS</main-class>"
+ "<java-opts>-Xmx2048m -Dkey1=val1</java-opts>"
+ "</java>");
@@ -1765,7 +1858,9 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
// heap size (2048 + 512)
heapSize = ae.extractHeapSizeMB(launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS));
- assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx1536m -Xmx2048m -Dkey1=val1 -Xmx2560m",
+ assertEquals("-Xmx200m -Xmx1536m -Xmx2048m -Dkey1=val1", launcherConf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx200m -Xmx1536m -Xmx2048m -Dkey1=val1", launcherConf.get("mapreduce.map.java.opts"));
+ assertEquals("-Xmx1024m -Djava.net.preferIPv4Stack=true -Xmx200m -Xmx1536m -Xmx2048m -Dkey1=val1 -Xmx2560m",
launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS).trim());
assertEquals(2560, heapSize);
@@ -1780,7 +1875,7 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
+ "<configuration>"
+ "<property><name>oozie.launcher.yarn.app.mapreduce.am.command-opts</name>"
+ "<value>-Xmx2048m -Djava.net.preferIPv4Stack=true </value></property>"
- + "<property><name>oozie.launcher.mapred.child.java.opts</name><value>-Xmx3072m</value></property>"
+ + "<property><name>oozie.launcher.mapreduce.map.java.opts</name><value>-Xmx3072m</value></property>"
+ "</configuration>" + "<main-class>MAIN-CLASS</main-class>"
+ "<java-opts>-Xmx1024m -Dkey1=val1</java-opts>"
+ "</java>");
@@ -1789,7 +1884,9 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase {
// heap size (2048 + 512)
heapSize = ae.extractHeapSizeMB(launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS));
- assertEquals("-Xmx2048m -Djava.net.preferIPv4Stack=true -Xmx3072m -Xmx1024m -Dkey1=val1 -Xmx2560m",
+ assertEquals("-Xmx200m -Xmx3072m -Xmx1024m -Dkey1=val1", launcherConf.get("mapred.child.java.opts"));
+ assertEquals("-Xmx200m -Xmx3072m -Xmx1024m -Dkey1=val1", launcherConf.get("mapreduce.map.java.opts"));
+ assertEquals("-Xmx2048m -Djava.net.preferIPv4Stack=true -Xmx200m -Xmx3072m -Xmx1024m -Dkey1=val1 -Xmx2560m",
launcherConf.get(JavaActionExecutor.YARN_AM_COMMAND_OPTS).trim());
assertEquals(2560, heapSize);
}
http://git-wip-us.apache.org/repos/asf/oozie/blob/d77b0d8a/docs/src/site/twiki/WorkflowFunctionalSpec.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/WorkflowFunctionalSpec.twiki b/docs/src/site/twiki/WorkflowFunctionalSpec.twiki
index 40dcd1f..f7590d0 100644
--- a/docs/src/site/twiki/WorkflowFunctionalSpec.twiki
+++ b/docs/src/site/twiki/WorkflowFunctionalSpec.twiki
@@ -1421,9 +1421,21 @@ hcat://[metastore server]:[port]/[database name]/[table name]/[partkey1]=[value]
In case of a hcatalog URI, the hive-site.xml needs to be shipped using =file= tag and the hcatalog and hive jars
need to be placed in workflow lib directory or specified using =archive= tag.
-The =java-opts= element, if present, contains the command line parameters which are to be used to start the JVM that
-will execute the Java application. Using this element is equivalent to use the =mapred.child.java.opts= configuration
-property.
+The =java-opts= and =java-opt= elements, if present, contains the command line parameters which are to be used to start the JVM that
+will execute the Java application. Using this element is equivalent to using the =mapred.child.java.opts=
+or =mapreduce.map.java.opts= configuration properties, with the advantage that Oozie will append to these properties instead of
+simply setting them (e.g. if you have one of these properties specified in mapred-site.xml, setting it again in
+the =configuration= element will override it, but using =java-opts= or =java-opt= will instead append to it, preserving the original
+value). You can have either one =java-opts=, multiple =java-opt=, or neither; you cannot use both at the same time. In any case,
+Oozie will set both =mapred.child.java.opts= and =mapreduce.map.java.opts= to the same value based on combining them. In other
+words, after Oozie is finished:
+<verbatim>
+mapred.child.java.opts <-- "<mapred.child.java.opts> <mapreduce.map.java.opts> <java-opt...|java-opts>"
+mapreduce.map.java.opts <-- "<mapred.child.java.opts> <mapreduce.map.java.opts> <java-opt...|java-opts>"
+</verbatim>
+In the case that parameters are repeated, the latest instance of the parameter is used by Java. This means that =java-opt=
+(or =java-opts=) has the highest priority, followed by =mapreduce.map.java.opts=, and finally =mapred.child.java.opts=. When
+multiple =java-opt= are specified, they are included from top to bottom ordering, where the bottom has highest priority.
The =arg= elements, if present, contains arguments for the main function. The value of each =arg= element is considered
a single argument and they are passed to the =main= method in the same order.