Search code examples
javaeclipsejava-modulegluon-mobilejava-platform-module-system

Error modularizing a project with gluon Charm: The package com.gluonhq.charm.down.plugins is accessible from more than one module


I'm going through modularizing my own projects. One of my classes uses the following imports:

import com.gluonhq.charm.down.Services;
import com.gluonhq.charm.down.plugins.StorageService; // error here on "com.gluonhq.charm.down.plugins"
import com.gluonhq.charm.glisten.application.MobileApplication;
import com.gluonhq.charm.glisten.control.AppBar;
import com.gluonhq.charm.glisten.control.Dialog;
import com.gluonhq.charm.glisten.control.SettingsPane;
import com.gluonhq.charm.glisten.control.settings.DefaultOption;
import com.gluonhq.charm.glisten.control.settings.Option;
import com.gluonhq.charm.glisten.mvc.View;
import com.gluonhq.charm.glisten.visual.MaterialDesignIcon;

In my module-info.java I have declared:

requires charm.glisten;
requires charm.down.core;
requires charm.down.plugin.storage;

as per auto-fix suggestions of Eclipse. However, I get the error specified for the above line:

The package com.gluonhq.charm.down.plugins is accessible from more than one module:
charm.down.plugin.device,
charm.down.plugin.display,
charm.down.plugin.in.app.billing,
charm.down.plugin.lifecycle,
charm.down.plugin.push.notifications,
charm.down.plugin.runtime.args,
charm.down.plugin.statusbar,
charm.down.plugin.storage

The charm modules are automatically named since they are not Java modules apparently. This could be related to the issue. Before modularizing my projects, there were no such issues. How do I solve this?

build.gradle:

buildscript {
    repositories {
        jcenter()
        google()
        mavenCentral()
        maven {
            url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
        }
        maven {
            url 'https://plugins.gradle.org/m2/'
        }
    }
    dependencies {
        classpath 'com.gluonhq:client-gradle-plugin:0.1.30'
    }
}

plugins {
    id 'org.openjfx.javafxplugin' version '0.0.9'
    id 'org.beryx.jlink' version '2.21.2'
    id 'com.google.osdetector' version '1.6.2'
    id 'eclipse'
    id 'org.kordamp.gradle.jdeps' version '0.11.0'
}

apply plugin: 'com.gluonhq.client-gradle-plugin'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

sourceCompatibility = 14
targetCompatibility = 14

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

dependencies {
    compile "org.openjfx:javafx-base:14:$platform"
    compile "org.openjfx:javafx-graphics:14:$platform"
    compile "org.openjfx:javafx-controls:14:$platform"
    compile "org.openjfx:javafx-fxml:14:$platform"

    runtimeOnly "org.openjfx:javafx-graphics:14:win"
    runtimeOnly "org.openjfx:javafx-graphics:14:mac"
    runtimeOnly "org.openjfx:javafx-graphics:14:linux"

    compile 'com.gluonhq:charm:5.0.0-jdk9'
    compile 'org.reactfx:reactfx:2.0-M5'

    compileOnly "org.projectlombok:lombok:1.18.12"
    annotationProcessor 'org.projectlombok:lombok:1.18.12'
}


javafx {
    version = "14"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = 'com.my.app.MainClass'
jar {
    manifest {
        attributes 'Main-Class': 'com.my.app.Launcher'
    }
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

eclipse {
    classpath {
        downloadJavadoc = true
        downloadSources = true
    }
}

wrapper {
    gradleVersion = '6.5.1'
}

JDK 14
Eclipse 4.16
buid.gradle declares the dependency 'com.gluonhq:charm:5.0.0-jdk9' (I saw that version 6 exists, should I upgrade?)


Solution

  • The old Gluon jfxmobile plugin, that was used to create mobile applications with Java 1.8 or Java 9, is EOL.

    To be able to run those mobile applications with Java/JavaFX 11+, you have to replace that plugin new Gluon Client plugin.

    More details:

    One main difference, the new plugin uses Maven instead of Gradle. However, thanks to the community, there is also a version of the Client plugin for Gradle, that might be a little bit behind the maven counterpart).

    In order to migrate your project to Java 11+ and replace one plugin with the other, you have to modify your build file.

    plugins {
        // new client plugin
        id 'com.gluonhq.client-gradle-plugin' version '0.1.30'
    
        id 'org.openjfx.javafxplugin' version '0.0.9'
        id 'org.beryx.jlink' version '2.21.2'
        id 'com.google.osdetector' version '1.6.2'
        id 'eclipse'
        id 'org.kordamp.gradle.jdeps' version '0.11.0'
    }
    
    repositories {
        jcenter()
        maven {
            url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
        }
    }
    
    sourceCompatibility = 14
    targetCompatibility = 14
    
    dependencies {
       
        compile 'com.gluonhq:charm:6.0.5'
        compile 'org.reactfx:reactfx:2.0-M5'
    
        compileOnly "org.projectlombok:lombok:1.18.12"
        annotationProcessor 'org.projectlombok:lombok:1.18.12'
    }
    
    
    javafx {
        version = "14"
        modules = [ 'javafx.controls', 'javafx.fxml' ]
    }
    
    gluonClient {
     //    target = "ios"  // uncomment to deploy on iOS
     //    target = "android"  // uncomment to deploy on Android
    
          attachConfig {
             version = "4.0.8"
             services 'display', 'lifecycle', 'statusbar', 'storage'
         }
     }
    

    You will notice the main changes:

    • Charm (Gluon Mobile) is now 6.0+
    • Charm Down has been renamed to Attach, current version is 4.0.8 (you will have to refactor the package names, like com.gluonhq.charm.down.plugins.StorageService to com.gluonhq.attach.storage.StorageService).

    You can still run the project with your JDK, with ./gradlew run (using the JavaFX plugin).

    With the new Client plugin you will also be able to create a native image, that will run on desktop (Windows, Linux, MacOS) and mobile (Android, iOS), leveraging GraalVM.

    Following the Client requirements, download GraalVM for your host machine from here, set GRAALVM_HOME, and you will be able to run:

    // build the native image, it takes some time:
    ./gradlew clean nativeBuild
    // run the native image
    ./gradlew nativeRun
    

    And if you have a mobile device at hand, only by enabling the target to iOS or Android in your build will build and deploy the native image to that mobile platform.