invzbl3
invzbl3

Reputation: 6470

Java 11 package is declared in module which does not export it

I have created two modular programs. One is JavaFX modular project that contains module-info.java like:

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

Another Maven project that contains module-info.java like:

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

So, I added modular maven project as external jar into JavaFX (via Project Structure in libs and in module-info via requires I specified jar). Also I added variable that contains external jar for compilation (in addition to PATH_TO_FX and PATH_TO_FX_MODS):

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

But when I'm trying to compile the project via command:

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

following this tutorial

I'm getting from JavaFX project class the error:

\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 I imported in JavaFX project to use classes from external jar.

Updated:

If I add exports project; inside module-info.java of maven project then I see the error in JavaFX module-info.java:

enter image description here If I delete requires TextInputProgram; then I have another error from import:

enter image description here

Am I missing something here? I'm trying to get executable Jar of these two programs.

Upvotes: 2

Views: 24209

Answers (1)

José Pereda
José Pereda

Reputation: 45476

As discussed throughout the comments, there are a few possible issues here:

  • Module definition

  • Local jars and dependencies

Based on the modular projects posted, I'll create a small demo multi-modular project to explain both problems.

Maven multi-modular project

Using your IDE, create a Maven project, then add two modules, TextInputProgram and checker, like:

Parent 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;
}

(Code of both modules is irrelevant at this point).

Solutions included

Now note that you have to add this in the TextInputProgram module descriptor:

exports project to checker;

if you want to let checker module to access TextInputProgram's project package.

This will solve this error:

package project is declared in module TextInputProgram, which does not export it

Also, note that I've included this dependency in the checker project:

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

Even having two modules, under the same parent, you need to include the dependency from one module to the other. Otherwise this will fail (module not found):

requires TextInputProgram;

You can run mvn clean install in the TextInputProgram module, to install org.openjfx:TextInputProgram:1.0-SNAPSHOT in your local repository .m2.

Then you can run mvn clean javafx:run int the checker module, to run the GUI project.

It is worth mentioning that it is not a good idea to combine both maven dependencies with jar files. If you end up using both, you will get this error:

Module 'checker' reads 'project' from both 'TextInputProgram' and 'TextInputProgram'

This message means that there are two modules in the module path with the exact same name, one the maven dependency, the other one, the jar artifact.

In order to distribute your project and modules, it is better to use the maven approach, and avoid having jar files in lib folders. Later on your modules will be published as separated artifacts, and you won't need to modify your pom files (other than to update the version numbers).

Upvotes: 5

Related Questions