Barmaley
Barmaley

Reputation: 16363

Noname module issue with gradle dependency (Java 9)

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;
                    ^

Upvotes: 0

Views: 620

Answers (1)

Gimby
Gimby

Reputation: 5283

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.

Upvotes: 1

Related Questions