0

I'm trying to port existing JavaFX app to Java 9.

Here's build.gradle

plugins {
    id 'application'
    id 'java'
    id 'org.openjfx.javafxplugin' version '0.0.9'
}

repositories {
    mavenLocal()
    maven {
        url = uri('https://repo.maven.apache.org/maven2/')
    }
    flatDir {
        dirs 'libs'
    }
}

group = 'ru.mydomain.myapp.fx'
version = '0.7'
description = 'myAppFX'
java.sourceCompatibility = JavaVersion.VERSION_1_9

java {
    modularity.inferModulePath = true
}

sourceSets {
    main {
        java {
            srcDirs("src/common/java", "src/fx/java")
        }
        resources {
            srcDirs = ['src/fx/resources']
        }
    }
}

dependencies {
    implementation 'org.slf4j:slf4j-api:1.7.25'
    implementation 'com.j256.ormlite:ormlite-jdbc:5.0'
    //blah-blah
}

javafx {
    version = "15.0.1"
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.swing']
}
application {
    mainModule = 'mymodule.javafx'
    mainClass = 'ru.mydomain.myapp.fx.Main'
}

My module declaration:

module mymodule.javafx {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.swing;
    requires slf4j.api;
    requires ormlite.jdbc;

    // Export the package (needed by JavaFX to start the Application)
    // Replace "exports" with "opens" if "@FXML" is used in this module
    opens ru.mydomain.myapp.fx;

}

Problem is in unnamed modules generated by libraries declared in gradle's dependencies. In this particular case with slf4j. Yeahh, it's resolvable whenever I'd use newer library with declared module-info.java, but in case when I use old libraries w/o module-info.java I'm getting error messages like:

error: module not found: slf4j.api/ormlite.jdbc/etc...

As far as I understood problem is in so-called automatic/unnamed modules.

Any ideas, how to resolve this issue with noname modules generated by dependency libs?

Update

Exploring com.j256.ormlite:ormlite-jdbc:5.0 dependency

  1. It doesn't contain any Automatic-Module-Name in manifest
  2. Exact jar name is: ormlite-jdbc-5.0.jar
  3. Double checked - it's in compile classpath
  4. Exact error message is:
    module-info.java:7: error: module not found: ormlite.jdbc
    requires ormlite.jdbc;
                    ^
Barmaley
  • 16,638
  • 18
  • 73
  • 146

1 Answers1

1

Let's strip the problem down to the bare necessities: this is a Java module question, it is pretty much unrelated to either Gradle or JavaFX. So we only have to examine Java module documentation to find out what we can do.

And what I read is: there is always a module name. If a jar provides absolutely nothing the name of the module is the name of the jar file without the .jar extension. There is more to it though, the exact rules for the name derivation can be found here. I'll quote it just in case the link breaks:

The ".jar" suffix is removed.

If the name matches the regular expression "-(\d+(\.|$))" then the module name will be derived from the subsequence preceding the hyphen of the first occurrence. The subsequence after the hyphen is parsed as a Version and ignored if it cannot be parsed as a Version.

All non-alphanumeric characters ([^A-Za-z0-9]) in the module name are replaced with a dot ("."), all repeating dots are replaced with one dot, and all leading and trailing dots are removed.

As an example, a JAR file named "foo-bar.jar" will derive a module name "foo.bar" and no version. A JAR file named "foo-bar-1.2.3-SNAPSHOT.jar" will derive a module name "foo.bar" and "1.2.3-SNAPSHOT" as the version.

So you need to change that requires statement to match the automatic naming rules.

But of course ideally use jar versions which are not part of ancient history...

Here is a nice blog about automatic module naming, should there still be doubts.

Gimby
  • 5,095
  • 2
  • 35
  • 47
  • So in accordance of these rules dependency `com.j256.ormlite:ormlite-jdbc:5.0` should be translated to module named `ormlite.jdbc` am I right? – Barmaley Jul 01 '21 at 12:51
  • By the looks of it, that would be my interpretation yes. – Gimby Jul 01 '21 at 12:53
  • Hmmm... but it doesn't work, compiler reports that module `ormlite.jdbc` is absent – Barmaley Jul 01 '21 at 12:54
  • Hrm, indeed. Quite the impasse. Of course another explanation for a module not being found is because the jar is actually not on the classpath... Maybe update your question to provide the actual and full error message you are getting. – Gimby Jul 01 '21 at 13:00
  • Perhaps also look in the jars themselves to see if they do not contain that sneaky 'Automatic-Module-Name' line in the manifest that the linked article talks about? – Gimby Jul 01 '21 at 13:02
  • Yes I think automatic naming is a dead end, that is not your problem. It might still be for someone else though so I guess this answer has value regardless. I am curious about that flatDir element which is in your build file, that implies you pull libraries from both Maven and the project, doesn't it? I would expand on that a little more in the question too, detailing which libraries are local and which are from a maven repo. – Gimby Jul 02 '21 at 08:44
  • 1) `flatDir` points to local folder `libs`, which contains single file: `JIconExtract.jar` all others are from maven's repo. 2) Can it be problem that I'm declaring 2 source folders: `srcDirs("src/common/java", "src/fx/java")` and as a result during compilation IDE reports `module-info.java` is absent? – Barmaley Jul 02 '21 at 09:49