title: Py4j launch_gateway not connecting properly
body: <p>I am trying to use py4j to open up a gateway that I can use to pass objects from java into python. When I try to open a gateway with the py4j function <a href="https://www.py4j.org/py4j_java_gateway.html#py4j.java_gateway.launch_gateway" rel="nofollow noreferrer"><code>launch_gateway</code></a> it does not seem to properly connect to my Java class. However, when I launch my java class in the command line and then connect to it in python using <a href="https://www.py4j.org/py4j_java_gateway.html#py4j.java_gateway.JavaGateway" rel="nofollow noreferrer"><code>JavaGateway</code></a> everything works as expected. I would like to be able to use the built in method as I am sure that I am not accounting for things that have already been considered in the design of py4j, but I'm just not sure what I'm doing wrong.</p>
  
  <p>Let's say I wanted to create a gateway to the class <code>sandbox.demo.solver.UtilityReporterEntryPoint.class</code>. In the command line I can do this by executing the following:</p>
  
  <pre><code>java -cp /Users/grr/anaconda/share/py4j/py4j0.10.4.jar: sandbox.demo.solver.UtilityReporterEntryPoint py4j.GatewayServer
  </code></pre>
  
  <p>This launches as expected and I can use the methods in my class from within python after connecting to the gateway. So far so good.</p>
  
  <p>My understanding of the py4j documentation would lead me to believe I should do the following to launch the gateway in python:</p>
  
  <pre><code>port = launch_gateway(classpath='sandbox.demo.solver.UtilityReporterEntryPoint')
  params = GatewayParameters(port=port)
  gateway= JavaGateway(gateway_parameters=params)
  </code></pre>
  
  <p>I get no errors when executing these three lines, but when I try to access my java class methods with <code>gateway.entry_point.someMethod()</code> it fails with the following error:</p>
  
  <blockquote>
    <p>Py4JError: An error occurred while calling t.getReport. Trace:
    py4j.Py4JException: Target Object ID does not exist for this gateway :t
        at py4j.Gateway.invoke(Gateway.java:277)
        at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
        at py4j.commands.CallCommand.execute(CallCommand.java:79)
        at py4j.GatewayConnection.run(GatewayConnection.java:214)
        at java.lang.Thread.run(Thread.java:745)</p>
  </blockquote>
  
  <p>Obviously something is not getting called correctly within <code>launch_gateway</code> or I am feeding it the wrong information.</p>
  
  <p>In the py4j source code for <a href="https://github.com/bartdag/py4j/blob/master/py4j-python/src/py4j/java_gateway.py#L214-L332" rel="nofollow noreferrer"><code>launch_gateway</code></a> you can see that given the inputs you provide and those constructed by the function, a command is constructed that eventually gets called by <a href="https://docs.python.org/3.5/library/subprocess.html#subprocess.Popen" rel="nofollow noreferrer"><code>subprocess.Popen</code></a>. So given the input passed to <code>launch_gateway</code> above the command passed into <code>Popen</code> would be:</p>
  
  <pre><code>command = ['java', '-classpath', '/Users/grr/anaconda/share/py4j/py4j0.10.4.jar:sandbox.demo.solver.UtilityReporterEntryPoint', 'py4j.GatewayServer', '0']
  </code></pre>
  
  <p>Passing this command to <code>Popen</code> returns the listening port as expected. However, connecting to this listening port still does not allow access to my class methods. </p>
  
  <p>Finally, passing the command as a single string to Popen without the final argument ('0'), properly launches a gateway which again operates as expected. Having taken a glance at the Java source code for py4j.GatewayServer.class this makes no sense as the main method seems to indicate that the class should exit with status 1 if the length of arguments is 0.</p>
  
  <p>At this point I'm kind of at a loss. I can hack my way into a workable solution, but as I said I'm sure that ignores important aspects of the gateway behavior and I don't like hacky solutions. I'd love to tag @Barthelemy in this one, but hopefully he reads this. Thanks in advance for any help.</p>
  
  <p><strong>EDIT</strong> </p>
  
  <p>For now I have been able to work around this issue with the following steps.</p>
  
  <ol>
  <li><p>Package entire project including all external dependencies into a single jar file <code>magABM-all.jar</code>, with 'Main-Class' set to <code>UtilityReporterEntryPoint</code>.</p></li>
  <li><p>Include <code>if...else</code> block regarding presence of <code>--die-on-exit</code> exactly like it is in <a href="https://github.com/bartdag/py4j/blob/master/py4j-java/src/main/java/py4j/GatewayServer.java#L768-L800" rel="nofollow noreferrer"><code>GatewayServer.java</code></a></p></li>
  <li><p>Use <a href="https://docs.python.org/3.5/library/subprocess.html#subprocess.Popen" rel="nofollow noreferrer"><code>subprocess.Popen</code></a> to call the command to run the project jar.</p></li>
  </ol>
  
  <p>UtilityReporterEntryPoint.java</p>
  
  <pre><code>public static void main(String[] args) throws IOException {
    GatewayServer server = new GatewayServer(new UtilityReporterEntryPoint());
    System.out.println("Gateway Server Started");
    server.start();
    if (args[0].equals("--die-on-exit")) {
      try {
          BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in, Charset.forName("UTF-8")));
          stdin.readLine();
          System.exit(0);
      } catch (java.io.IOException e) {
          System.exit(1);
      }
    }
  }
  </code></pre>
  
  <p>app.py</p>
  
  <pre><code>def setup_gateway()
      """Launch a py4j gateway using UtilityReporterEntryPoint."""
      process = subprocess.Popen('java -jar magABM-all.jar --die-on-exit', shell=True)
      time.sleep(0.5)
      gateway = JavaGateway()
      return gateway
  </code></pre>
  
  <p>In this way I can still use <code>gateway.shutdown</code> if necessary and if the python process that starts the py4j gateway dies or is closed the gateway will be closed.</p>
  
  <p><strong>N.B</strong> I would by no means consider this a final solution as py4j was written by much smarter individuals with a clear purpose in mind and I am sure that there is a way to manage this exact workflow within the confines of py4j. This is just a stopgap solution.</p>