Java 11程序包在不导出的模块中声明

时间:2019-08-08 22:46:50

标签: java javafx

我创建了两个模块化程序。一个是JavaFX模块化项目,其中包含module-info.java,例如:

module checker {
    requires javafx.fxml;
    requires javafx.controls;
    requires TextInputProgram; // Btw, IDEA shows me here "Ambiguous module reference"
    exports sample;
    opens sample;
}

另一个包含module-info.java的Maven项目,例如:

module TextInputProgram {
    requires selenium.api;
    requires selenium.chrome.driver;
}

因此,我将模块化maven项目作为外部jar添加到JavaFX中(通过我指定了jar的requires通过libs和module-info中的Project Structure)。我还添加了一个变量,该变量包含用于编译的外部jar(除了PATH_TO_FXPATH_TO_FX_MODS之外):

set EXTERNAL_JAR="...\out\artifacts\TextInputProgram_jar"

但是当我尝试通过命令编译项目时:

dir /s /b src\*.java > sources.txt & javac --module-path %EXTERNAL_JAR%;%PATH_TO_FX% -d mods/checker @sources.txt & del sources.txt

跟随this tutorial

我从JavaFX项目类中收到错误:

\src\sample\Controller.java:9: error: package project is not visible
import project.SeleniumProgram;
       ^
  (package project is declared in module TextInputProgram, which does not export it)
1 error

Package is declared in module which does not export it

import project.SeleniumProgram我在JavaFX项目中导入以使用来自外部jar的类。

已更新:

如果我在Maven项目的module-info.java中添加exports project;,那么我会在JavaFX module-info.java中看到错误:

enter image description here 如果删除requires TextInputProgram;,则导入时会出现另一个错误:

enter image description here

我在这里错过了什么吗?我正在尝试获取这两个程序的可执行Jar。

1 个答案:

答案 0 :(得分:1)

正如在评论中讨论的那样,这里存在一些可能的问题:

  • 模块定义

  • 本地jar和依赖项

基于发布的模块化项目,我将创建一个小型演示多模块化项目来解释这两个问题。

Maven多模块项目

使用您的IDE,创建一个Maven项目,然后添加两个模块TextInputProgramchecker,例如:

父母pom

<groupId>org.openjfx</groupId>
<artifactId>hellofx</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
    <module>TextInputProgram</module>
    <module>checker</module>
</modules>
<packaging>pom</packaging>

TextInputProgram pom

<parent>
    <groupId>org.openjfx</groupId>
    <artifactId>hellofx</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>TextInputProgram</artifactId>

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

<dependencies>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.141.59</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <release>11</release>
            </configuration>
        </plugin>
    </plugins>
</build>

Module-info.java

module TextInputProgram {
    requires selenium.api;
    requires selenium.chrome.driver;

    exports project to checker;
}

Checker pom

<parent>
    <artifactId>testMods</artifactId>
    <groupId>org.openjfx</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>checker</artifactId>

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>12.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>12.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>TextInputProgram</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <release>11</release>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>0.0.3</version>
            <configuration>
                <mainClass>sample.Main</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

Module-info.java

module checker {
    requires javafx.fxml;
    requires javafx.controls;
    requires TextInputProgram;

    opens sample to javafx.fxml;

    exports sample;
}

(此时两个模块的代码都无关紧要)。

包括解决方案

现在请注意,您必须在TextInputProgram模块描述符中添加它:

exports project to checker;

如果您想让checker模块访问TextInputProgram的{​​{1}}软件包。

这将解决此错误:

  

包项目在模块TextInputProgram中声明,该模块不会导出

另外,请注意,我已经在project项目中包括了这种依赖关系:

checker

即使在同一个父项下有两个模块,也需要包括从一个模块到另一个模块的依赖关系。否则,它将失败(找不到模块):

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>TextInputProgram</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

您可以在requires TextInputProgram; 模块中运行mvn clean install,以将TextInputProgram安装在本地存储库org.openjfx:TextInputProgram:1.0-SNAPSHOT中。

然后,您可以在.m2中运行mvn clean javafx:run来运行GUI项目。

值得一提的是,将两个Maven依赖项与jar文件结合起来并不是一个好主意。如果最终同时使用这两种方法,则会出现此错误:

  

模块'checker'从'TextInputProgram'和'TextInputProgram'读取'项目'

此消息表示模块路径中有两个模块具有完全相同的名称,一个是maven依赖项,另一个是jar工件。

为了分发项目和模块,最好使用maven方法,并避免在lib文件夹中包含jar文件。稍后,您的模块将作为单独的工件发布,并且您无需修改​​pom文件(除了更新版本号)。