Ошибка: «Пакет объявлен как« javafx.beans.value »в модуле« foo.bar »» - PullRequest
0 голосов
/ 11 ноября 2018

Я разработал библиотеку, которая module-info.java выглядит так:

module foo.bar {
  requires org.apache.commons.lang3;
  requires javafx.base;
  requires java.validation;
  exports foo.bar;
}

Эта библиотека используется в другом проекте, где module-info.java содержит следующее:

module other.project {
  requires org.apache.commons.lang3;
  requires javafx.base;
  requires javafx.graphics;
  requires javafx.fxml;
  requires foo.bar;
}

Когда я пытаюсь использовать import javafx.beans.value.WritableValue;, я получаю ошибку

Пакет javafx.beans.value объявлен в foo.bar, что не экспортировать его в модуль other.project.

ОБНОВЛЕНИЕ: Я создал два примера проектов, которые воспроизводят проблему. Пожалуйста, найдите их здесь для загрузки.

Я не понимаю, почему это так, и все же я не смог найти решение.

1 Ответ

0 голосов
/ 14 ноября 2018

Основываясь на опубликованном проекте здесь , ошибка, которую вы получаете при открытии проекта:

Пакет 'javafx.beans.property' объявлен в модуле 'com.example.external.lib', который не экспортирует его в модуль 'example.project'

Причиной этой ошибки является то, что вы добавляете некоторые пакеты из javafx.base во внешнюю библиотеку, но они не экспортируются в проект, который использует эту библиотеку. Пакет javafx.beans.property внутренне используется внешним модулем, но не может быть экспортирован .

Итак, вот некоторые предлагаемые изменения, чтобы заставить его работать.

Если вы создаете модульный jar (используя класс module-info) в качестве зависимости для другого проекта, вам не нужно использовать плагин shadow, и вам не нужно bundle зависимости JavaFX в ваших банках.

  1. Проект внешней библиотеки

Таким образом, вы можете иметь тот же module-info.java файл:

module com.example.external.lib {
    requires javafx.base;
    requires org.apache.commons.lang3;

    exports com.example.external.library;
}

с build.gradle вот так:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
    }
}

apply plugin: 'com.google.osdetector'
apply plugin: 'java'

ext.platform = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os

sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.8.1'
    compile "org.openjfx:javafx-base:11:$platform"
}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.base'
        ]
    }
}

Теперь, когда вы запустите gradle build, вы сгенерируете libs/external-library.jar, банку объемом 2 КБ, без зависимостей JavaFX.

Обратите внимание, что если вы все еще хотите создать теневой jar-файл с этим внешним проектом, вы можете использовать compileOnly "org.openjfx:javafx-base:11:$platform", чтобы сохранить зависимости JavaFX от этого jar-файла.

  1. Проект-с использованием внешнего-Пб

Вы можете добавить эту банку в проект.

build.gradle

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
    }
}

apply plugin: 'com.google.osdetector'
apply plugin: 'java'

ext.platform = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os

sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    compile files('libs/external-library.jar')
    compile 'org.apache.commons:commons-lang3:3.8.1'
    compile "org.openjfx:javafx-base:11:$platform"
}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.base'
        ]
    }
}

Но теперь ваш module-info файл должен снова включать зависимость javafx.base:

module example.project {
    requires javafx.base;
    requires com.example.external.lib;

    exports com.example.project;
}

Вы можете запустить gradle build, чтобы сгенерировать банку, и IntelliJ больше не будет жаловаться.

Если вы хотите получить теневую банку в конце, вы также можете применить:

buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
    }
}

apply plugin: 'application'
apply plugin: 'com.google.osdetector'

ext.platform = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os

sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    compile files('libs/external-library.jar')
    compile 'org.apache.commons:commons-lang3:3.8.1'
    compile "org.openjfx:javafx-base:11:$platform"
}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.base'
        ]
    }
}

run {
    doFirst {
        jvmArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.base'
        ]
    }
}

mainClassName = "com.example.project.PublicClass"

jar {
    manifest {
        attributes 'Main-Class': 'com.example.project.PublicClass'
    }
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

, чтобы вы могли запустить java -jar build/libs/project-using-external-lib.jar. Обратите внимание, что этот jar будет содержать классы JavaFX.

Создание теневого фляги не является рекомендуемым способом распространения вашего проекта, но, поскольку у вас есть автоматические модули (commons-lang3), вы не можете использовать jlink, если вы не конвертируете это в явный модуль (см. Это *) 1065 * ответ ).

...