Maven включает зависимости JavaFX для операционной системы, в которой я в настоящее время работаю, даже когда я классифицирую другие

#java #maven #javafx

Вопрос:

Я пытаюсь включить зависимости JavaFX только для mac OS, но win все еще загружаются. То же самое относится и к ДЕП linux.

pom.xml:

 <dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-graphics</artifactId>
    <version>11.0.2</version>
    <classifier>linux</classifier>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>11.0.2</version>
    <classifier>linux</classifier>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-fxml</artifactId>
    <version>11.0.2</version>
    <classifier>linux</classifier>
</dependency>
 

Мэйвен депс:

депс

pom.xml:

 <dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-graphics</artifactId>
    <version>11.0.2</version>
    <classifier>mac</classifier>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>11.0.2</version>
    <classifier>mac</classifier>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-fxml</artifactId>
    <version>11.0.2</version>
    <classifier>mac</classifier>
</dependency>
 

Мэйвен депс:

депс

Как удалить библиотеки win JavaFX или заставить Maven не загружать их?

То же самое происходит, когда я использую Ubuntu (Linux). Когда я классифицирую, мне нужны библиотеки mac, библиотеки Linux также загружаются и т. Д.

Возможно, стоит отметить, что я использую Eclipse IDE 2021-03 как в Windows, так и в Ubuntu.

Комментарии:

1. Вы работаете над Windows?

2. @gkhaos Да, это так. Я обновлю информацию, если то же самое произойдет в Linux с библиотеками Linux.

3. @gkhaos То же самое происходит в Linux.

Ответ №1:

Когда вы используете JavaFX с помощью артефактов Maven из Maven Central, вы обычно добавляете в свой pom:

     <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>16</version>
        </dependency>
    </dependencies>
 

и это просто работает на вашей платформе, нет необходимости в классификаторах.

Теперь, если вы проверите зависимости, например, в Linux, вы обнаружите:

 $ mvn dependency:tree

[INFO]  org.openjfx:javafx-controls:jar:16:compile
[INFO]     - org.openjfx:javafx-controls:jar:linux:16:compile
[INFO]    - org.openjfx:javafx-graphics:jar:16:compile
[INFO]        - org.openjfx:javafx-graphics:jar:linux:16:compile
[INFO]       - org.openjfx:javafx-base:jar:16:compile
[INFO]          - org.openjfx:javafx-base:jar:linux:16:compile
 

То же самое, если вы работаете в Windows или Mac OS.

Вы можете догадаться, как javafx-controls получает зависимости от обхода: через его pom. Но как он получает классификатор?

Давайте проверим помпон:

 <project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>16</version>
    <parent>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx</artifactId>
        <version>16</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>16</version>
            <classifier>${javafx.platform}</classifier>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>16</version>
        </dependency>
    </dependencies>
</project>
 

Как вы можете видеть, уже применен классификатор, основанный на свойстве ${javafx.platform} maven.

Это свойство разрешается с помощью родительского pom:

     <parent>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx</artifactId>
        <version>16</version>
    </parent>
 

Если вы проверите его содержимое:

 <project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>16</version>
<packaging>pom</packaging>
<name>openjfx</name>
<description>OpenJFX JavaFX</description>
<url>https://openjdk.java.net/projects/openjfx/</url>
<properties>
    <javafx.version>16</javafx.version>
</properties>
<dependencyManagement></dependencyManagement>
<profiles>
    <profile>
        <id>linux</id>
        <activation>
            <os>
                <name>linux</name>
            </os>
        </activation>
        <properties>
            <javafx.platform>linux</javafx.platform>
        </properties>
    </profile>
    // windows profile
    // mac profile
...
 

Таким образом, это означает , что существует профиль, который активируется на основе вашей текущей платформы и автоматически устанавливает свойство ${javafx.platform} , которое, в свою очередь, устанавливает ваш классификатор зависимостей.

Итак, что произойдет, если вы добавите другой классификатор в свою зависимость от JavaFX (например, вы работаете в Linux):

     <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>16</version>
            <classifier>win</classifier>
        </dependency>
    </dependencies>
 

вы получите:

 $ mvn dependency:tree

[INFO] - org.openjfx:javafx-controls:jar:win:16:compile
[INFO]     - org.openjfx:javafx-controls:jar:linux:16:compile
[INFO]    - org.openjfx:javafx-graphics:jar:16:compile
[INFO]        - org.openjfx:javafx-graphics:jar:linux:16:compile
[INFO]       - org.openjfx:javafx-base:jar:16:compile
[INFO]          - org.openjfx:javafx-base:jar:linux:16:compile
 

Зависимость верна, сначала вы получаете версию win, но затем у ее собственного pom есть зависимость javafx-controls:${javafx.platform} , которая решается на основе вашей платформы (т. Е. Linux), и это объясняет, почему вы также получаете артефакт платформы.

Я не вижу, как этого можно избежать, так как вы не можете отключить активацию профиля внутри pom зависимости.

Редактировать

Если вы продолжаете читать родительский pom javafx, есть этот профиль:

 <profile>
            <id>javafx.platform.custom</id>
            <activation>
                <property>
                    <name>javafx.platform</name>
                </property>
            </activation>
            <properties>
                <javafx.platform>${javafx.platform}</javafx.platform>
            </properties>
        </profile>
 

это профиль, который активируется, если javafx.platform он установлен, и он переопределяет предыдущие значения значения ${javafx.platform}.

Поэтому я только что попробовал в Linux (без добавления какого-либо классификатора к зависимости):

 $ mvn -Djavafx.platform=win dependency:tree

[INFO] com.gluonhq.samples:hellopi:jar:1.0.0-SNAPSHOT
[INFO] - org.openjfx:javafx-controls:jar:16:compile
[INFO]     - org.openjfx:javafx-controls:jar:win:16:compile
[INFO]    - org.openjfx:javafx-graphics:jar:16:compile
[INFO]        - org.openjfx:javafx-graphics:jar:win:16:compile
[INFO]       - org.openjfx:javafx-base:jar:16:compile
[INFO]          - org.openjfx:javafx-base:jar:win:16:compile
 

и это работает, больше никаких классификаторов платформ.

Тем не менее, в вашей среде IDE могут отображаться зависимости от платформы, но пока вы работаете с этим свойством (например mvn -Djavafx.platform=win javafx:run ), это должно работать.

Комментарии:

1. Спасибо за объяснение. Может ${javafx.platform} ли или моя платформа быть «подделана» (возможно, в pom.xml) быть чем-то другим? Это может решить мою проблему, потому что у меня есть 3 проекта maven, каждый для каждой платформы.

2. Да, по крайней мере частично. Смотрите мою правку. Однако, возможно, вы захотите переосмыслить, зачем вам нужны три проекта?

3. Просто для информации я хотел создать одно и то же приложение javafx для каждой платформы, но не хотел включать все библиотеки для каждой платформы в одну банку. Это разделение на 3 проекта пришло мне в голову как хорошая идея, так как я не профессионал в Maven и не нашел там учебника, как это сделать в одном проекте. Эти 3 проекта теперь имеют общий код через зависимость от 4-го проекта, но имеют библиотеки javafx для одной конкретной платформы соответственно. И да, IDE все еще показывает deps, но это-D javafx.платформа… работает.

4. Отлично, тогда подумайте о том, чтобы отметить ответ как принятый, он может быть полезен и другим.

Ответ №2:

Краткий ответ для Eclipse IDE:

Конфигурация сборки

Создайте три конфигурации сборки maven для каждой платформы и укажите параметр javafx.platform со значением win, linux или mac для каждой конфигурации.

Это не что иное, как добавление "-Djavafx.platform={platform}" к mvn команде.

Однако в зависимостях Maven в Eclipse IDE будут отображаться и другие зависимости от платформы.