Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: module-info missing for > JDK 9 not usable with jlink #902

Open
lanthale opened this issue Feb 17, 2020 · 13 comments
Open

BUG: module-info missing for > JDK 9 not usable with jlink #902

lanthale opened this issue Feb 17, 2020 · 13 comments

Comments

@lanthale
Copy link

Description:
If I want to package an application for Windows/OSX/... I need to create a jlink distribution of the app which requires that the application and all it's libraries are modularized.
For libraries that means that a multi-release jar is created which includes for > JDK9 a module-info.java.

actual behavior: no module-info.java is present for > JDK 9
expected behavior: module-info inside the already existing multi-release jar is present.

Thank you for this very good component. My target is to create a simple texteditor for very very big files (>100 GB files) which I have to search for patterns. This is actually only possible with VIM/VI on linux. This should be possible as well with javafx and your component.

@Jugen
Copy link
Collaborator

Jugen commented Feb 18, 2020

So RichTextFX depends on ReactFX, UndoFX, Flowless, and WellBehavedFX which are all no longer maintained and will probably not be modularized.

I can however add an Automatic-Module-Name: org.fxmisc.richtext entry to RichTextFX's jar manifest and hopefully that'll help. Otherwise there is also the RichTextFX fat (uber) jar in releases.

@lanthale
Copy link
Author

lanthale commented Feb 18, 2020

I am not speaking about modularizing of the library.
It is enough to just add the module-info.java file sitting in the java9 directory of the multi-release jar.

I can deliver the file because I patched richtextfx already to be usable in my modular application and attach it here. It is just adding the file and compile afterwards. That*s it.

@Jugen
Copy link
Collaborator

Jugen commented Feb 18, 2020

That would be great thanks :-)

@lanthale
Copy link
Author

lanthale commented Feb 18, 2020

I have tried to re-compile with gradle. But gradle is somehow totaly different than maven and therefore I could not get the whole thing compiled.

Place the following content in a file with name module-info.java under the folder 'java9'. After you compile you should get a jar file which includes under java9 the module-info.class.

Here is the content of the module-info.java (I cannot attach the file):

module richtextfx.fat {
    requires javafx.controls;    
    
    exports org.fxmisc.richtext.model;
    exports org.fxmisc.richtext.event;
    exports org.fxmisc.richtext.util;
}

Hopefully it is working. Otherwise I have to dig down the issue why gradle does not want to find the javafx library.

@Jugen
Copy link
Collaborator

Jugen commented Feb 21, 2020

I've released RichTextFX version 0.10.4 could you try it and give me feedback please.

@lanthale
Copy link
Author

lanthale commented Feb 21, 2020

I have tried the 10.4 version but it has not helped.

So the module-info.class Is necessary for working with jlink.

@Jugen
Copy link
Collaborator

Jugen commented Feb 26, 2020

Like you, I also couldn't get it to work with gradle .... so in the end I did it manually.

Could you please download richtextfx-fat-0.10.4.zip and see if that works (not only for jlink but afterwards during runtime as well).

Note that the zip is actually a jar (which Github doesn't like) so just rename the extension after downloading.

@lanthale
Copy link
Author

lanthale commented Feb 26, 2020

Thank you for the lib which is now working.

I have found out that some packages which I am using are not exported. Here is now a modified module-info.java file which should than finally work:

Here is the final module-info.java

module richtextfx.fat {
    requires javafx.controls;    
    
    exports org.fxmisc.richtext;
    exports org.fxmisc.richtext.model;
    exports org.fxmisc.richtext.event;
    exports org.fxmisc.richtext.util;
    exports org.fxmisc.wellbehaved.event;
    exports org.fxmisc.flowless;
    exports org.fxmisc.undo;
}

With that module-info the lib is usable with jlink.

@Jugen
Copy link
Collaborator

Jugen commented Feb 27, 2020

Yip, that's what I thought would happen and is why I mentioned the RichTextFX dependencies before ....
Anyway after more manual trickery please try richtextfx-fat-0.10.4.zip and see if this works now. (I expect that there might still be one more tweak ..... ?)

@lanthale
Copy link
Author

I have tried it and it worked perfectly. Thank you for providing this.

Hopefully you can integrate this file into the gradle build somehow.

Actually I am using richtextfx to create a simple editor which has not file size limit. Similar to VI/VIM. Thank you for this great component.

@mkpaz
Copy link

mkpaz commented Sep 25, 2020

In case someone interested RichTextFX can be integrated into modular app with awesome Moditect plugin that automates jdeps and jlink commands usage. Configuration is a little bit tricky though, because jdeps somehow generates incorrect modules names for the RichTextFX dependencies. Tested with JDK15. If you're using lower version it may require to play with jdeps --multi-release option.

<properties>
    <bld.compression>2</bld.compression>
    <bld.descriptor>windows.xml</bld.descriptor>
    <bld.distribDirectory>${project.build.directory}/dist</bld.distribDirectory>
    <bld.mainClass>myapp.Launcher</bld.mainClass>
    <bld.modulesDirectory>${project.build.directory}/modules</bld.modulesDirectory>
    <bld.platform>win64</bld.platform>
    <bld.runtimeImagesDirectory>${project.build.directory}/runtime-images</bld.runtimeImagesDirectory>
</properties>

<!-- copies app to the modules dir -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <outputDirectory>${bld.modulesDirectory}</outputDirectory>
    </configuration>
</plugin>

<!-- copies all (both modularized and not modularized) dependencies to the modules dir -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${bld.modulesDirectory}</outputDirectory>
                <includeScope>runtime</includeScope>
            </configuration>
        </execution>
    </executions>
</plugin>

<!-- injects module-info to specified dependencies  -->
<plugin>
    <groupId>org.moditect</groupId>
    <artifactId>moditect-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>add-module-info-richtextfx</id>
            <phase>package</phase>
            <goals>
                <goal>add-module-info</goal>
            </goals>
            <configuration>
                <outputDirectory>${bld.modulesDirectory}</outputDirectory>
                <overwriteExistingFiles>true</overwriteExistingFiles>
                 <modules>
                     <module>
                         <artifact>
                             <groupId>org.reactfx</groupId>
                             <artifactId>reactfx</artifactId>
                         </artifact>
                         <moduleInfoSource>
                             module org.reactfx {
                             requires transitive javafx.base;
                             requires transitive javafx.controls;
                             requires transitive javafx.graphics;

                             exports org.reactfx;
                             exports org.reactfx.collection;
                             exports org.reactfx.inhibeans;
                             exports org.reactfx.inhibeans.binding;
                             exports org.reactfx.inhibeans.collection;
                             exports org.reactfx.inhibeans.property;
                             exports org.reactfx.inhibeans.value;
                             exports org.reactfx.util;
                             exports org.reactfx.value;
                             }
                         </moduleInfoSource>
                     </module>
                     <module>
                         <artifact>
                             <groupId>org.fxmisc.flowless</groupId>
                             <artifactId>flowless</artifactId>
                         </artifact>
                         <moduleInfoSource>
                             module org.fxmisc.flowless {
                             requires transitive javafx.base;
                             requires transitive javafx.controls;
                             requires transitive javafx.graphics;
                             requires transitive org.reactfx;

                             exports org.fxmisc.flowless;
                             }
                         </moduleInfoSource>
                     </module>
                     <module>
                         <artifact>
                             <groupId>org.fxmisc.wellbehaved</groupId>
                             <artifactId>wellbehavedfx</artifactId>
                         </artifact>
                         <moduleInfoSource>
                             module org.fxmisc.wellbehaved {
                             requires transitive javafx.base;
                             requires transitive javafx.graphics;

                             exports org.fxmisc.wellbehaved.event;
                             exports org.fxmisc.wellbehaved.event.internal;
                             exports org.fxmisc.wellbehaved.event.template;
                             }
                         </moduleInfoSource>
                     </module>
                     <module>
                         <artifact>
                             <groupId>org.fxmisc.undo</groupId>
                             <artifactId>undofx</artifactId>
                         </artifact>
                         <moduleInfoSource>
                             module org.fxmisc.undo {
                             requires transitive javafx.base;
                             requires transitive org.reactfx;

                             exports org.fxmisc.undo;
                             exports org.fxmisc.undo.impl;
                             }
                         </moduleInfoSource>
                     </module>
                    <module>
                        <artifact>
                            <groupId>org.fxmisc.richtext</groupId>
                            <artifactId>richtextfx</artifactId>
                        </artifact>
                        <moduleInfoSource>
                            module org.fxmisc.richtext {

                            requires transitive javafx.base;
                            requires transitive javafx.controls;
                            requires transitive javafx.graphics;

                            requires transitive org.reactfx;
                            requires transitive org.fxmisc.flowless;
                            requires transitive org.fxmisc.undo;
                            requires org.fxmisc.wellbehaved;

                            exports org.fxmisc.richtext;
                            exports org.fxmisc.richtext.event;
                            exports org.fxmisc.richtext.model;
                            exports org.fxmisc.richtext.util;
                            }
                        </moduleInfoSource>
                    </module>
                </modules>
            </configuration>
        </execution>
    </executions>
</plugin>

<!-- generates runtime image -->
<plugin>
    <groupId>org.moditect</groupId>
    <artifactId>moditect-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>create-runtime-image-${bld.platform}</id>
            <phase>package</phase>
            <goals>
                <goal>create-runtime-image</goal>
            </goals>
            <configuration>
                <baseJdk>version=${java.version},platform=${bld.platform}</baseJdk>
                <modulePath>
                    <path>${bld.modulesDirectory}</path>
                </modulePath>
                <modules>
                    <module>myapp</module>
                </modules>
                <launcher>
                    <name>myapp</name>
                    <module>myapp/${bld.mainClass}</module>
                </launcher>
                <outputDirectory>${bld.runtimeImagesDirectory}/${bld.platform}</outputDirectory>
                <compression>${bld.compression}</compression>
            </configuration>
        </execution>
    </executions>
</plugin>

@Jugen
Copy link
Collaborator

Jugen commented Sep 25, 2020

@mkpaz  Great, thanks for that !

@Siedlerchr
Copy link

we only use the CodeArea and that works out of the box inside a modularized application.
If you are using gradle, I can recommend having a look at https://github.com/beryx/badass-jlink-plugin that helps also in identifying potential conflicts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants