Heroku不允许创建/读取进程。

huangapple go评论90阅读模式
英文:

Heroku not allowing creating/reading from process

问题

以下是您提供的内容的中文翻译:

我正在一个涉及从另一个进程读取数据的项目上工作,当我注意到它不断抛出 java.util.NoSuchElementException: 找不到行 错误时,我创建了一个 Maven 测试应用程序来检查是 Heroku 的问题还是我的程序的问题。

src/main/java/com/test/App.java:

package com.test;
import java.util.Arrays;
import java.util.Scanner;
import java.io.IOException;
public class App{
    public static void main(String[] args) throws IOException{
        System.out.println(new Scanner(new ProcessBuilder(Arrays.asList("java", "A")).start().getInputStream()).nextLine());
    }
}

A.java:

public class A{
    public static void main(String[] args){
        System.out.println("Test");
    }
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.test</groupId>
  <artifactId>test</artifactId>
  <version>1.0</version>

  <name>test</name>
  <!-- FIXME 将其更改为项目的网站 -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- 锁定插件版本以避免使用 Maven 默认值(可能移到父 POM 中) -->
      <plugins>
        <!-- clean 生命周期,参见 https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- 默认生命周期,jar 打包:参见 https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
          <configuration>
            <archive>
              <manifest>
                <mainClass>com.test.App</mainClass>
              </manifest>
            </archive>
          </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site 生命周期,参见 https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

在执行了 javac A.javamvn installjava -jar target/test-1.0.jar 之后,在我的电脑上打印出了 "Test",但在 Heroku 上抛出了 NoSuchElementException

完整的堆栈跟踪:

Exception in thread "main" java.util.NoSuchElementException: 找不到行
    at java.util.Scanner.nextLine(Scanner.java:1540)
    at com.test.App.main(App.java:7)

是否有人知道是什么原因造成了这个问题,以及如何修复它?

编辑:附上了 Github 仓库 以希望能更清楚地表达。

编辑编辑:奇怪的是,如果我将 A.java 放在 src/main/java 中,并使用 @Malax 回答中的命令,它就能正常工作,但我仍然不明白为什么 Heroku 看不到在 src 之外的 Java 文件。也许它们被修剪以节省空间?

英文:

I was working on a project involving reading from another process when I noticed that it kept throwing java.util.NoSuchElementException: No line found, so I made a Maven test application to check that it was Heroku's fault instead of my program's.

src/main/java/com/test/App.java:

package com.test;
import java.util.Arrays;
import java.util.Scanner;
import java.io.IOException;
public class App{
public static void main(String[] args) throws IOException{
System.out.println(new Scanner(new ProcessBuilder(Arrays.asList(&quot;java&quot;, &quot;A&quot;)).start().getInputStream()).nextLine());
}
}

A.java:

public class A{
public static void main(String[] args){
System.out.println(&quot;Test&quot;);
}
}

pom.xml:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

  &lt;groupId&gt;com.test&lt;/groupId&gt;
  &lt;artifactId&gt;test&lt;/artifactId&gt;
  &lt;version&gt;1.0&lt;/version&gt;

  &lt;name&gt;test&lt;/name&gt;
  &lt;!-- FIXME change it to the project&#39;s website --&gt;
  &lt;url&gt;http://www.example.com&lt;/url&gt;

  &lt;properties&gt;
    &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;maven.compiler.source&gt;1.7&lt;/maven.compiler.source&gt;
    &lt;maven.compiler.target&gt;1.7&lt;/maven.compiler.target&gt;
  &lt;/properties&gt;

  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;junit&lt;/groupId&gt;
      &lt;artifactId&gt;junit&lt;/artifactId&gt;
      &lt;version&gt;4.11&lt;/version&gt;
      &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;

  &lt;build&gt;
    &lt;pluginManagement&gt;&lt;!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --&gt;
      &lt;plugins&gt;
        &lt;!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-clean-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.1.0&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.0.2&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.8.0&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
          &lt;version&gt;2.22.1&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.0.2&lt;/version&gt;
          &lt;configuration&gt;
            &lt;archive&gt;
              &lt;manifest&gt;
                &lt;mainClass&gt;com.test.App&lt;/mainClass&gt;
              &lt;/manifest&gt;
            &lt;/archive&gt;
          &lt;/configuration&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-install-plugin&lt;/artifactId&gt;
          &lt;version&gt;2.5.2&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-deploy-plugin&lt;/artifactId&gt;
          &lt;version&gt;2.8.2&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-site-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.7.1&lt;/version&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-project-info-reports-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.0.0&lt;/version&gt;
        &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/pluginManagement&gt;
  &lt;/build&gt;
&lt;/project&gt;

After javac A.java, mvn install, and java -jar target/test-1.0.jar, it prints "Test" on my computer, but throws a NoSuchElementException in Heroku.

Full Stacktrace:

Exception in thread &quot;main&quot; java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at com.test.App.main(App.java:7)

Does anyone know what's causing this and how to fix it?

Edit: Attatched Github repo to hopefully make it clearer

Edit Edit: Oddly, if I put A.java in src/main/java and use the command from @Malax's answer, it works, but I still don't get why Heroku isn't seeing the java file outside of src. Maybe it's trimming them out to save space?

答案1

得分: 1

问题发生是因为您在Scanner上调用nextLine而没有检查是否有一行内容。您需要使用hasNext进行检查,以确保nextLine不会失败。

导致您没有获取到行的根本原因是在调用java时没有指定类路径。如果没有指定类路径,java将无法找到您编译的A类,并且会失败并显示类似于以下内容的错误:

错误:找不到或加载主类 A
原因:java.lang.ClassNotFoundException: A

这个错误消息不会被getInputStream捕获。如果您使用getErrorStream,您将能够读取错误消息(但这样您就无法获取STDOUT消息)。

这与Heroku无关,我只能猜测为什么在本地对您起作用。要为java提供类路径,您可以使用-cp

ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList("java", "-cp", "target/classes", "A"));
Scanner scanner = new Scanner(processBuilder.start().getInputStream());
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
英文:

The issue occurs because you're calling nextLine on Scanner without checking if there even is a line. You need to check with hasNext to ensure nextLine will not fail.

The underlying reason why you get no lines is that you're not specifying a classpath when invoking java. java will not be able to find your compiled A class without it and fail with something like

Error: Could not find or load main class A
Caused by: java.lang.ClassNotFoundException: A

on STDERR which you don't capture with getInputStream. You will be able to read the error message when you use getErrorStream instead (but then you won't get the STDOUT messages).

This has nothing to do with Heroku and I can only speculate why this is working for you locally. To provide java a classpath, you can use -cp:

ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList(&quot;java&quot;, &quot;-cp&quot;, &quot;target/classes&quot;, &quot;A&quot;));
Scanner scanner = new Scanner(processBuilder.start().getInputStream());
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}

huangapple
  • 本文由 发表于 2020年10月28日 02:22:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64560669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定