Repository: pantsbuild/pants

Issue:
JVM run task broken in 1.11.dev0
In 1.11.dev0 running a jvm run task doesn't work. The error we get is:
```
Exception caught: (<type 'exceptions.TypeError'>)

Exception message: can only concatenate list (not "NoneType") to list
```

The root cause seems to be this commit: https://github.com/pantsbuild/pants/commit/71467604c5d43df6000995346f245f3768441c03

The target should default to `[]` (we don't use any extra jvm options) but it seems the `get_field_value` might be run on a wrong target here: https://github.com/pantsbuild/pants/commit/71467604c5d43df6000995346f245f3768441c03#diff-330c9a1c6b6b5df53b8e2eae2f383035R85

I get the required empty list if I change `target.payload....` to `binary.payload...`


Discussion:
@pall-valmundsson : Thanks for filing!

I don't repro with:
```
./pants run examples/src/scala/org/pantsbuild/example:jvm-run-example
```
in the pantsbuild/pants repo.

Could you describe the steps needed to repro this?
Modification to that BUILD file to repro is adding:
```
jvm_app(
  name='jvm-app-run-example',
  binary=':jvm-run-example',
  dependencies=[':jvm-run-example'],
)
```

And running: ```./pants run examples/src/scala/org/pantsbuild/example:jvm-app-run-example```
Ahh, gotcha. Thanks!

Resolving patch:
diff --git a/src/python/pants/backend/jvm/tasks/jvm_run.py b/src/python/pants/backend/jvm/tasks/jvm_run.py
--- a/src/python/pants/backend/jvm/tasks/jvm_run.py
+++ b/src/python/pants/backend/jvm/tasks/jvm_run.py
@@ -80,9 +80,11 @@ def execute(self):
     else:
       binary = target
 
-    # Some targets will not have extra_jvm_options in their payload,
-    # so we can't access it with target.payload.extra_jvm_options
-    extra_jvm_options = target.payload.get_field_value("extra_jvm_options")
+    # This task is installed in the "run" goal.
+    # This means that, when invoked with ./pants run, it will run regardless of whether
+    # the target is a jvm target.
+    # As a result, not all targets passed here will have good defaults for extra_jvm_options
+    extra_jvm_options = binary.payload.get_field_value("extra_jvm_options", [])
 
     # We can't throw if binary isn't a JvmBinary, because perhaps we were called on a
     # python_binary, in which case we have to no-op and let python_run do its thing.
diff --git a/testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options/main.py b/testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options/main.py
new file mode 100644
--- /dev/null
+++ b/testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options/main.py
@@ -0,0 +1,2 @@
+if __name__ == '__main__':
+  print("Python app runs correctly")


Test patch:
diff --git a/tests/python/pants_test/backend/jvm/tasks/test_jvm_run_integration.py b/tests/python/pants_test/backend/jvm/tasks/test_jvm_run_integration.py
--- a/tests/python/pants_test/backend/jvm/tasks/test_jvm_run_integration.py
+++ b/tests/python/pants_test/backend/jvm/tasks/test_jvm_run_integration.py
@@ -72,3 +72,33 @@ def test_disable_synthetic_jar(self):
        '--no-jvm-synthetic-classpath',
        'testprojects/tests/java/org/pantsbuild/testproject/syntheticjar:run']).stdout_data
     self.assertIn('Synthetic jar run is not detected', output)
+
+  def test_enable_extra_jvm_options(self):
+    output = self.run_pants(
+      ['run',
+        'testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options:python_app']).stdout_data
+    self.assertIn('Python app runs correctly', output)
+
+    output = self.run_pants(
+      ['run',
+        'testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options:noopts']).stdout_data
+    self.assertIn("""Property property.color is null
+Property property.size is null
+Flag -DMyFlag is NOT set
+Max Heap Size: 954728448""", output)
+
+    output = self.run_pants(
+      ['run',
+        'testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options:app_noopts']).stdout_data
+    self.assertIn("""Property property.color is null
+Property property.size is null
+Flag -DMyFlag is NOT set
+Max Heap Size: 954728448""", output)
+
+    output = self.run_pants(
+      ['run',
+        'testprojects/src/java/org/pantsbuild/testproject/extra_jvm_options:opts']).stdout_data
+    self.assertIn("""Property property.color is orange
+Property property.size is 2
+Flag -DMyFlag is set
+Max Heap Size: 1572864""", output)