我有一个RDX俄罗斯方块克隆,最初是使用ide和maven进行依赖关系管理而制作的.一切都运行得很好--但是,我想知道一切都是如何工作的,所以我试图在不使用ide或maven的情况下在我的ubuntu终端中编译和运行该应用程序.

我的项目 struct 中有所有javafx依赖项和SQlite-jdbc驱动程序/slj 4 jar.

以下是我try 编译和运行该应用程序时所采取的步骤:

  1. CD进入项目根目录~/Tetris,其中包含目录lib、bin和SRC.Lib包含javafx模块,bin用于.Class文件输出和项目资源(图像文件、声音文件、高分数据库),SRC包含源代码.

  2. 编写程序:

    javac --module-track lib --add-modules javafx.base,javafx. controlls,javafx.graphics,wwwjavafx.media bin src/main/java/com/example/tetris/*.Java

到目前为止,一切都很顺利.

  1. 运行程序:

    Java--模块路径lib--add-modules javafx. base,javafx. controlls,www.example.com,www.example.com-cp bin:lib/SQlite-jdbc-3.45.3.0.jar:lib/sl4j-api-1.7.36.jar SRC/main/Java/com/example/tetris/www.example.com

在此命令中,我将SQLite驱动程序和sl4 j添加到类路径中并try 运行该程序.首先,我得到的控制台输出表明程序正在运行: 已成功创建表格"top_players". 表中的行数:3 N:AAA,S:10000 N:BBB,S:5000

但不久之后,它崩溃了,我得到了这个神秘的错误:

Exception in Application start method
Exception in thread "main" java.lang.IllegalArgumentException: 0 > -4
    at java.base/java.util.Arrays.copyOfRange(Arrays.java:3782)
    at java.base/java.util.Arrays.copyOfRange(Arrays.java:3742)
    at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:431)
    at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:192)
    at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:132)

这就是它给我的全部信息,没有其他信息.有人知道我可能错过了什么或做错了什么吗?

如果有帮助的话,我使用的是Ubuntu系统.我已经在PATH中添加了jdk和javafx.我真的被难住了.感谢任何看到并回复的人.

推荐答案

该错误(我认为)是可以用以下内容复制:

import javafx.application.Application;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        throw new RuntimeException("test");
    }

    public static void main(String[] args) {
        launch(Main.class, args);
    }
}

命令行:

java -p <path-to-javafx> --add-modules javafx.graphics Main.java

输出:

Exception in Application start method
Exception in thread "main" java.lang.IllegalArgumentException: 0 > -2
        at java.base/java.util.Arrays.copyOfRange(Arrays.java:3807)
        at java.base/java.util.Arrays.copyOfRange(Arrays.java:3767)
        at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.execute(SourceLauncher.java:273)
        at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.run(SourceLauncher.java:153)
        at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.main(SourceLauncher.java:78)

这个crytpic错误的来源似乎是JEP 330/458的handling of InvocationTargetException(链接到Java 22源代码).我对该代码的理解是,当main引发异常时,它试图从堆栈跟踪中隐藏SourceLauncher方法.在大多数情况下,这似乎效果良好.然而,无论出于何种原因,如果源文件的主类是MEK应用程序,并且launchstart引发异常而引发异常,那么上述代码就会失败,并且您会看到非法参数异常隐藏了真正的问题.

无论如何,您首先要编译您的程序,因此您不应该首先使用JEP 330功能.这意味着您应该通过class namejava,而不是source file.根据您在问题中提供的信息,您的命令应该是:

java --module-path lib \
     --add-modules javafx.controls,javafx.media \
     --class-path bin:lib/sqlite-jdbc-3.45.3.0.jar:lib/sl4j-api-1.7.36.jar \
     com.example.tetris.Main

请注意几件事:

  1. 最后一位是主类的完全限定名称(而不是源文件的路径).此类将位于类路径上.

  2. --add-modules中仅包含javafx.controlsjavafx.media need,因为其他所需的PFA模块将被这两个需要它们的模块隐式拉入.尽管显式添加每个单独的PFA模块并没有错误,只是没有必要.

  3. 您可以使用-cp而不是--class-path,也可以使用-p而不是--module-path.

也就是说,您的应用程序仍然可能引发异常.但现在您应该能够看到真正的异常,而不是那个神秘的IllegalArgumentException.


您在标题中提到您正在运行一个"模块化应用程序".如果您的意思是your own code是模块化的(即,您有一个module-info.java文件),那么您的命令实际上应该是:

java --module-path lib:bin --module app/com.example.tetris.Main

Note:您可以使用-p代替--module-path,也可以使用-m代替--module.

假设您的模块描述符看起来类似于:

module app {
    requires java.sql;
    requires javafx.controls;
    requires javafx.media;

    exports com.example.tetris to
        javafx.graphics;
}

Note:如果您自己的代码使用requires org.slf4j,则包括它.否则,包括sqlite-jdbc driver requires it already.类似地,如果您直接使用它,则可以使用requires org.xerial.sqlitejdbc,否则您应该通过服务Provider 机制来找到它(java.sql模块usesorg.xerial.sqlitejdbc模块provides的服务).


1.我曾为此提交过一个错误,但因"不可复制"而被拒绝.该 comments 解释了他们试图复制它的方法,但他们未能使用JEP 330.我的后续行动没有收到任何回应.因此,据我所知,OpenJK开发人员仍然没有意识到这个问题.

Java相关问答推荐

使用SaxonJ HE在收件箱中摆脱regex

在Java中使用带限制的回归打印星形三角形

计算战舰沉船/船只的问题(Java)

为什么接口中的主函数而不是类中的主函数在Java 17中编译和运行没有问题?

try 使用Java 9或更高版本对特殊对象图进行解析时出现NullPointerException

为什么Java Annotation接口覆盖对象类中的方法

Java流传输一个列表并创建单个对象

在Spring终结点中,是否可以同时以大写和小写形式指定枚举常量?

如何使用Jackson将XML元素与值和属性一起封装

无法在Java中处理PayPal支付响应

声明MessageChannel Bean的首选方式

在使用具有不同成本的谓词调用allMatch之前对Java流进行排序会带来什么好处吗?

JavaFX复杂项目体系 struct

为什么JavaFX MediaPlayer音频播放在Windows和Mac上运行良好,但在Linux(POPOS/Ubuntu)上却有问题?

当使用不同的参数类型调用时,为什么围绕Objects.equals的类型安全包装不会失败?

如何修复Spring Boot应用程序中的RestDocumentationGenerationException:java.io.FileNotFoundException:/curl-request.adoc(只读文件系统)?

如何设置默认序列生成器分配大小

如何在JSP中从select中获取值并将其放入另一个select

javax.crypto-密码对象-提供者服务是如何工作的?

获取月份';s在java中非UTC时区的开始时间和结束时间