【问题标题】:IllegalAccessException: cannot access class C (in module M) because module M does not export C to module NIllegalAccessException:无法访问类 C(在模块 M 中),因为模块 M 没有将 C 导出到模块 N
【发布时间】:2021-08-29 07:03:12
【问题描述】:

我正在尝试将 Maven 支持添加到我拥有的现有 JavaFX 项目中。

我从关注 OpenJFX 的 Getting Started Guide 开始,它教您如何使用 Maven 编译和运行 Hello World JavaFX 应用程序。完成后,我将项目的文件粘贴到这个新项目中并进行了所需的更改。我的文件夹结构或多或少是这样的:

src/main/
  java/
    org.openjfx/
      Main.java
      components/
      controllers/
  resources/org.openjfx/fxml/

为了运行项目,我使用以下 Maven 命令:

compiler:compile
javafx:compile
javafx:run

但是,我收到了这个错误:

应用程序启动方法中的异常 原因:java.lang.IllegalAccessException:类 javafx.fxml.FXMLLoader$ValueElement(在模块 javafx.fxml 中)无法访问类 org.openjfx.controllers.LoginController(在模块 org.openjfx 中)因为模块 org.openjfx 不导出 org .openjfx.controllers 到模块 javafx.fxml

这似乎很奇怪,因为显然我正在导出 module-info.java 中的内容:

module org.openjfx {
    requires javafx.controls;
    requires javafx.fxml;

    opens org.openjfx to javafx.fxml;
    exports org.openjfx;
}

我想知道将我的包命名为 org.openjfx 是不是一个坏主意,并且可能会导致问题,但我只是按照教程进行操作。

以下是我的pom.xml 文件,如果有任何相关性:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.openjfx</groupId>
    <artifactId>hellofx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>11</maven.compiler.release>
        <javafx.version>13</javafx.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>${maven.compiler.release}</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <configuration>
                    <mainClass>org.openjfx.App</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

【问题讨论】:

  • 看起来您的控制器(例如)位于主包的子包中。我相信您需要显式打开该子包,以便javafx.fxml 能够通过反射访问它:即将opens org.openjfx.controllers to javafx.fxml; 添加到module-info.java。
  • 见鬼,这行得通!我之前尝试添加exports org.openjfx.controllers,但没有成功。这工作很顺利。非常感谢!如果您将此添加为答案,我将很高兴接受它。
  • 请注意,我不会使用 org.openjfx 作为您的模块名称或包根目录(当然,除非您正在为 OpenJFX 编写代码)。
  • 我不是。我只是按照教程进行操作,因为我不知道自己在做什么。什么是更合适的命名? com.project-name?
  • 嗯,这对于个人项目来说并不重要(在 JPMS 限制之外,例如没有拆分包)。但是,如果您曾经编写过与世界共享的库或应用程序,那么您的想法是选择一个唯一的 group-id/artifact-id 并使用它来派生您的根包名称。我相信 group-id/artifact-id 的概念来自 Maven。已有信息建议如何选择合适的值。也就是说,由于这是一个个人项目,并且您正在尝试学习 JavaFX,所以我暂时忽略我所说的并专注于更重要的事情。

标签: java maven javafx


【解决方案1】:

javafx.fxml 模块实例化控制器类,并通过反射访问其中的字段和方法。为了使其工作,您需要 open 包含 javafx.fxml 模块的任何控制器的特定包。

This 是了解模块系统的好资源。引用自它:

open、opens 和 opens…to。 在 Java 9 之前,反射可用于了解包中的所有类型和类型的所有成员——甚至 它的私有成员——您是否希望允许此功能或 不是。因此,没有什么是真正封装的。

模块系统的一个关键动机是强大的封装性。经过 默认情况下,模块中的类型不能被其他模块访问,除非 它是一个公共类型,你导出它的包。你只暴露 要公开的包。对于 Java 9,这也适用于 反射。

...

允许特定模块仅在运行时访问包。一个 opens…to 形式的模块指令

opens package to comma-separated-list-of-modules 

表示一个 特定包的公共类型(及其嵌套的公共和受保护的 types) 只能在运行时被列出的模块中的代码访问。 指定包中的所有类型(以及所有类型的 成员)可以通过反射访问指定的代码 模块。

请注意,您打开的是 packages,而不是 modules。由于您的控制器位于子包 org.openjfx.controllers 中(我认为您应该更改基本包名称),因此您需要显式打开该子包(可能还有其他子包)。

因此,添加

opens org.openjfx.controllers to javafx.fxml ;

到您的module-info.java 文件应该可以解决问题

【讨论】:

  • 我几乎放弃了添加 Maven。您的帮助非常重要。非常感谢!
猜你喜欢
  • 2019-05-07
  • 2023-02-20
  • 2021-10-16
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
相关资源
最近更新 更多