Ceylon 模块系统:Guava class 不匹配,即使依赖项树中只有一个 Guava

Ceylon module system: Guava class mismatch even though there's only one Guava in dependencies tree

我正在为 JSimpleDB(持久性库)定义适配器,方法是将 class 子类化,该 Google Guava Converter 作为构造函数参数:

shared class RoleConverter() extends Converter<Role, String>() {
    shared actual Role doBackward(String? name) {
        "Cannot convert null to role."
        assert (exists name);
        return Role.ofName(name);
    }

    shared actual String doForward(Role? role) {
        return role?.name else "null";
    }
}

shared class RoleType() extends StringEncodedType<Role>(
    javaClass<Role>(),
    0,
    RoleConverter()
) {
}

JSimpleDB 默认不导出 Guava,因此我添加了以下 overrides.xml 以确保正确的 类 对我的应用程序可见(我没有使用 --auto-export-maven-depencies--flat-classpath):

<overrides xmlns="http://www.ceylon-lang.org/xsd/overrides">
    <module groupId="org.jsimpledb" artifactId="jsimpledb-coreapi">
        <share groupId="com.google.guava" artifactId="guava" />
    </module>
    <module groupId="org.jsimpledb" artifactId="jsimpledb-main">
        <!-- guava is already shared by jsimpledb-coreapi -->
        <remove groupId="com.google.guava" artifactId="guava" />
        <share groupId="org.jsimpledb" artifactId="jsimpledb-coreapi" />
        <share groupId="org.jsimpledb" artifactId="jsimpledb-util" />
        <share groupId="org.dellroad" artifactId="dellroad-stuff-main" />
    </module>
</overrides>

这导致以下模块层次结构(我的代码在 fun.uschool.user.impl 中):

正确的 com.google.guava:guava 模块应该暴露给我的程序,我确实可以导入 Converter,但是当我尝试编译上面的代码时,我得到以下错误:

source/fun/uschool/user/impl/userImpl.ceylon:156: error: argument must be assignable to parameter 'arg2' of 'StringEncodedType': 'RoleConverter' is not assignable to 'Converter<Role,String>?'
    RoleConverter()
    ^
source/fun/uschool/user/impl/userImpl.ceylon:153: error: Ceylon backend error: no suitable constructor found for StringEncodedType(no arguments)
shared class RoleType() extends StringEncodedType<Role>(
^
    constructor StringEncodedType.StringEncodedType(Class<Role>,long,Converter<Role,String>) is not applicable
      (actual and formal argument lists differ in length)
    constructor StringEncodedType.StringEncodedType(String,Class<Role>,long,Converter<Role,String>) is not applicable
      (actual and formal argument lists differ in length)
Note: Created module fun.uschool.feature.spi/1.0.0
Note: Created module fun.uschool.user.api/1.0.0
Note: Created module fun.uschool.feature.impl/1.0.0
Note: Created module fun.uschool.user.impl/1.0.0
ceylon compile: There were 2 errors

所以显然不知何故导入了错误的 com.google.guava:guava,即使在模块依赖关系树中只有 1 个可见。 如何导入正确的?

这里是 ceylon info 的依赖分析的输出:

$ ceylon info fun.uschool.user.impl/1.0.0 --dependency-depth=all
Namespace:   ceylon
Name:        fun.uschool.user.impl
Version:     1.0.0
Artifacts:   JVM (#8.1), Sources
Available:   On local system
Origin:      /home/ilmoeuro/Asiakirjat/Projektit/youschool/modules
Dependency Tree (up to depth ∞):
  ceylon.buffer/1.3.2
      ceylon.collection/1.3.2
          ceylon.language/1.3.2
      ceylon.interop.java/1.3.2
          shared ceylon.collection/1.3.2 (already imported)
          ceylon.language/1.3.2 (already imported)
          shared java.base/7
      ceylon.language/1.3.2 (already imported)
      java.base/7 (already imported)
  ceylon.interop.java/1.3.2 (already imported)
  ceylon.language/1.3.2 (already imported)
  ceylon.test/1.3.2
      ceylon.collection/1.3.2 (already imported)
      ceylon.file/1.3.2
          ceylon.language/1.3.2 (already imported)
          java.base/7 (already imported)
      ceylon.language/1.3.2 (already imported)
      ceylon.runtime/1.3.2
          shared ceylon.language/1.3.2 (already imported)
          shared com.redhat.ceylon.cli/1.3.2
              shared com.redhat.ceylon.common/1.3.2
                  shared java.base/7 (already imported)
                  java.desktop/7
                  shared java.logging/7
              shared com.redhat.ceylon.module-resolver/1.3.2
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.langtools.classfile/1.3.2
                      shared java.base/7 (already imported)
                  shared com.redhat.ceylon.model/1.3.2
                      shared com.redhat.ceylon.common/1.3.2 (already imported)
                      shared com.redhat.ceylon.langtools.classfile/1.3.2 (already imported)
                      shared java.base/7 (already imported)
                      shared java.logging/7 (already imported)
                  optional com.redhat.ceylon.module-resolver-aether/1.3.2
                  optional com.redhat.ceylon.module-resolver-javascript/1.3.2
                  optional com.redhat.ceylon.module-resolver-webdav/1.3.2
                  shared java.base/7 (already imported)
                  shared java.logging/7 (already imported)
                  javax.jaxws/7
                  javax.script/7
                  shared javax.xml/7
              shared java.base/7 (already imported)
              java.desktop/7 (already imported)
              shared java.logging/7 (already imported)
              shared optional org.tautua.markdownpapers.core/1.2.7
          shared com.redhat.ceylon.common/1.3.2 (already imported)
          shared com.redhat.ceylon.model/1.3.2 (already imported)
          shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
          com.redhat.ceylon.tool.provider/1.3.2
              ceylon.language/1.3.2 (already imported)
              shared com.redhat.ceylon.cli/1.3.2 (already imported)
              shared com.redhat.ceylon.common/1.3.2 (already imported)
              shared com.redhat.ceylon.compiler.java/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  com.github.rjeschke.txtmark/0.13
                      shared java.base/7 (already imported)
                  shared com.redhat.ceylon.cli/1.3.2 (already imported)
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.langtools.classfile/1.3.2 (already imported)
                  shared com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  shared com.redhat.ceylon.typechecker/1.3.2
                      shared com.redhat.ceylon.common/1.3.2 (already imported)
                      shared com.redhat.ceylon.model/1.3.2 (already imported)
                      shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                      shared java.base/7 (already imported)
                      shared org.antlr.runtime/3.4
                          shared java.base/7 (already imported)
                          shared org.antlr.stringtemplate/3.2.1
                              shared java.base/7 (already imported)
                              shared java.desktop/7 (already imported)
                              shared org.antlr.antlr/2.7.7
                                  shared java.base/7 (already imported)
                                  shared java.desktop/7 (already imported)
                  shared java.base/7 (already imported)
                  shared java.compiler/7
                  java.desktop/7 (already imported)
                  java.logging/7 (already imported)
                  java.prefs/7
                  shared javax.xml/7 (already imported)
                  oracle.jdk.base/7
                  shared org.antlr.runtime/3.4 (already imported)
              com.redhat.ceylon.compiler.js/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  shared com.redhat.ceylon.cli/1.3.2 (already imported)
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  com.redhat.ceylon.module-resolver-javascript/1.3.2
                      net.minidev.json-smart/1.1.1
                          shared java.base/7 (already imported)
                  shared com.redhat.ceylon.typechecker/1.3.2 (already imported)
                  shared java.base/7 (already imported)
                  shared java.logging/7 (already imported)
                  net.minidev.json-smart/1.1.1 (already imported)
                  shared org.antlr.runtime/3.4 (already imported)
              com.redhat.ceylon.model/1.3.2 (already imported)
              com.redhat.ceylon.module-loader/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  com.redhat.ceylon.common/1.3.2 (already imported)
                  com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  shared java.base/7 (already imported)
                  optional org.jboss.modules/1.4.4.Final
              shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
              com.redhat.ceylon.typechecker/1.3.2 (already imported)
              shared java.base/7 (already imported)
              org.jboss.modules/1.4.4.Final
                  shared java.base/7 (already imported)
                  shared java.instrument/7
                  shared java.logging/7 (already imported)
                  java.management/7
                  java.prefs/7 (already imported)
                  shared javax.xml/7 (already imported)
                  oracle.jdk.base/7 (already imported)
          shared java.base/7 (already imported)
          java.compiler/7 (already imported)
          shared java.instrument/7 (already imported)
          javax.xml/7 (already imported)
          org.jboss.logmanager/2.0.3.Final
              shared java.base/7 (already imported)
              shared java.logging/7 (already imported)
              java.management/7 (already imported)
              shared java.tls/7
              optional org.jboss.modules/1.4.4.Final
          shared org.jboss.modules/1.4.4.Final (already imported)
      java.base/7 (already imported)
      org.jboss.modules/1.4.4.Final (already imported)
  shared fun.uschool.feature.impl/1.0.0
      ceylon.buffer/1.3.2 (already imported)
      ceylon.interop.java/1.3.2 (already imported)
      ceylon.language/1.3.2 (already imported)
      shared maven:com.moandjiezana.toml:toml4j/0.7.1
          maven:com.google.code.gson:gson/2.3.1
      shared fun.uschool.feature.spi/1.0.0
          ceylon.language/1.3.2 (already imported)
      shared java.base/8 (already imported other version)
      shared maven:org.jsimpledb:jsimpledb-main/3.5.0
          maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED
          maven:javax.el:javax.el-api/2.2.5
          maven:javax.validation:validation-api/1.1.0.Final
          maven:log4j:log4j/1.2.17 RUNTIME
              optional maven:javax.mail:mail/1.4.3
              optional maven:org.apache.geronimo.specs:geronimo-jms_1.1_spec/1.0
              maven:org.apache.openejb:javaee-api/5.0-2 PROVIDED
          maven:org.dellroad:dellroad-stuff-main/2.1.0
              optional maven:au.com.bytecode:opencsv/2.4
              maven:com.google.guava:guava/21.0
                  optional maven:com.google.code.findbugs:jsr305/1.3.9
                  optional maven:com.google.errorprone:error_prone_annotations/2.0.15
                  optional maven:com.google.j2objc:j2objc-annotations/1.1
                  optional maven:org.codehaus.mojo:animal-sniffer-annotations/1.14
              maven:javax.validation:validation-api/1.1.0.Final (already imported)
              optional maven:jline:jline/2.14.2
              optional maven:log4j:log4j/1.2.17
              optional maven:org.apache.ant:ant/1.9.7
              optional maven:org.hibernate.javax.persistence:hibernate-jpa-2.1-api/1.0.0.Final
              optional maven:org.hibernate:hibernate-core/5.0.7.Final
              maven:org.slf4j:slf4j-api/1.7.25
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME
                  maven:log4j:log4j/1.2.17 (already imported)
                  maven:org.slf4j:slf4j-api/1.7.25 (already imported)
              optional maven:org.springframework:spring-context/4.3.7.RELEASE
          maven:org.hibernate:hibernate-validator/5.2.4.Final
              maven:com.fasterxml:classmate/1.1.0
              optional maven:com.thoughtworks.paranamer:paranamer/2.5.5
              maven:javax.el:javax.el-api/2.2.4 PROVIDED (already imported other version)
              maven:javax.validation:validation-api/1.1.0.Final (already imported)
              optional maven:joda-time:joda-time/2.7
              maven:org.glassfish.web:javax.el/2.2.4 PROVIDED
                  maven:javax.el:javax.el-api/2.2.4 (already imported other version)
              optional maven:org.hibernate.javax.persistence:hibernate-jpa-2.1-api/1.0.0.Final
              maven:org.jboss.logging:jboss-logging/3.2.1.Final
                  maven:log4j:log4j/1.2.16 PROVIDED (already imported other version)
                  maven:org.apache.logging.log4j:log4j-api/2.0 PROVIDED
                      maven:org.osgi:org.osgi.core/4.3.1 PROVIDED
                  maven:org.jboss.logmanager:jboss-logmanager/1.5.2.Final PROVIDED
                      optional maven:org.jboss.modules:jboss-modules/1.1.0.GA PROVIDED
                  maven:org.slf4j:slf4j-api/1.7.2 PROVIDED (already imported other version)
              maven:org.jboss.logging:jboss-logging-processor/1.2.0.Final PROVIDED
                  maven:org.jboss.jdeparser:jdeparser/1.0.0.Final
                  maven:org.jboss.logging:jboss-logging/3.1.2.GA PROVIDED (already imported other version)
                  maven:org.jboss.logging:jboss-logging-annotations/1.2.0.Final
                      maven:org.jboss.logging:jboss-logging/3.1.2.GA PROVIDED (already imported other version)
              optional maven:org.jsoup:jsoup/1.8.3
          shared maven:org.jsimpledb:jsimpledb-coreapi/3.5.0
              maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
              maven:commons-codec:commons-codec/1.10
              maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
              maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
              maven:org.jsimpledb:jsimpledb-kv/3.5.0
                  maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
                  maven:com.google.guava:guava/21.0 (already imported)
                  maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
                  maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
                  maven:org.jsimpledb:jsimpledb-util/3.5.0
                      maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
                      shared maven:com.google.guava:guava/21.0 (already imported)
                      maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
                      maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
                      maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
                  maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
                  maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
              shared maven:org.jsimpledb:jsimpledb-util/3.5.0 (already imported)
              maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
          maven:org.jsimpledb:jsimpledb-kv/3.5.0 (already imported)
          maven:org.jsimpledb:jsimpledb-kv-simple/3.5.0
              maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
              maven:com.google.guava:guava/21.0 (already imported)
              maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
              maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
              maven:org.jsimpledb:jsimpledb-kv/3.5.0 (already imported)
              maven:org.jsimpledb:jsimpledb-util/3.5.0 (already imported)
              maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
          maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
          maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
  shared fun.uschool.feature.spi/1.0.0 (already imported)
  shared fun.uschool.user.api/1.0.0
      ceylon.language/1.3.2 (already imported)
      shared fun.uschool.feature.spi/1.0.0 (already imported)
      fun.uschool.user.impl/1.0.0
          ceylon.buffer/1.3.2 (already imported)
          ceylon.interop.java/1.3.2 (already imported)
          ceylon.language/1.3.2 (already imported)
          ceylon.test/1.3.2 (already imported)
          shared fun.uschool.feature.impl/1.0.0 (already imported)
          shared fun.uschool.feature.spi/1.0.0 (already imported)
          shared fun.uschool.user.api/1.0.0 (already imported)
          shared java.base/8 (already imported other version)
  shared java.base/8 (already imported other version)

Dependencies (up to depth ∞):
  ceylon.buffer/1.3.2
  ceylon.collection/1.3.2
  ceylon.file/1.3.2
  ceylon.interop.java/1.3.2
  ceylon.language/1.3.2
  ceylon.runtime/1.3.2
  ceylon.test/1.3.2
  com.fasterxml:classmate/1.1.0
  com.github.rjeschke.txtmark/0.13
  com.google.code.findbugs:jsr305/3.0.1
  com.google.code.gson:gson/2.3.1
  com.google.guava:guava/21.0
  com.moandjiezana.toml:toml4j/0.7.1
  com.redhat.ceylon.cli/1.3.2
  com.redhat.ceylon.common/1.3.2
  com.redhat.ceylon.compiler.java/1.3.2
  com.redhat.ceylon.compiler.js/1.3.2
  com.redhat.ceylon.langtools.classfile/1.3.2
  com.redhat.ceylon.model/1.3.2
  com.redhat.ceylon.module-loader/1.3.2
  com.redhat.ceylon.module-resolver/1.3.2
  com.redhat.ceylon.module-resolver-javascript/1.3.2
  com.redhat.ceylon.tool.provider/1.3.2
  com.redhat.ceylon.typechecker/1.3.2
  commons-codec:commons-codec/1.10
  fun.uschool.feature.impl/1.0.0
  fun.uschool.feature.spi/1.0.0
  fun.uschool.user.api/1.0.0
  fun.uschool.user.impl/1.0.0
  java.base: 7, 8
  java.compiler/7
  java.desktop/7
  java.instrument/7
  java.logging/7
  java.management/7
  java.prefs/7
  java.tls/7
  javax.el:javax.el-api: 2.2.4, 2.2.5
  javax.jaxws/7
  javax.script/7
  javax.validation:validation-api/1.1.0.Final
  javax.xml/7
  log4j:log4j: 1.2.16, 1.2.17
  net.minidev.json-smart/1.1.1
  oracle.jdk.base/7
  org.antlr.antlr/2.7.7
  org.antlr.runtime/3.4
  org.antlr.stringtemplate/3.2.1
  org.apache.logging.log4j:log4j-api/2.0
  org.apache.openejb:javaee-api/5.0-2
  org.dellroad:dellroad-stuff-main/2.1.0
  org.glassfish.web:javax.el/2.2.4
  org.hibernate:hibernate-validator/5.2.4.Final
  org.jboss.jdeparser:jdeparser/1.0.0.Final
  org.jboss.logging:jboss-logging: 3.1.2.GA, 3.2.1.Final
  org.jboss.logging:jboss-logging-annotations/1.2.0.Final
  org.jboss.logging:jboss-logging-processor/1.2.0.Final
  org.jboss.logmanager/2.0.3.Final
  org.jboss.logmanager:jboss-logmanager/1.5.2.Final
  org.jboss.modules/1.4.4.Final
  org.jsimpledb:jsimpledb-coreapi/3.5.0
  org.jsimpledb:jsimpledb-kv/3.5.0
  org.jsimpledb:jsimpledb-kv-simple/3.5.0
  org.jsimpledb:jsimpledb-main/3.5.0
  org.jsimpledb:jsimpledb-util/3.5.0
  org.osgi:org.osgi.core/4.3.1
  org.slf4j:slf4j-api: 1.7.2, 1.7.25
  org.slf4j:slf4j-log4j12/1.7.25

Dependencies version conflicts (up to depth ∞):
  java.base: 7, 8
  javax.el:javax.el-api: 2.2.4, 2.2.5
  log4j:log4j: 1.2.16, 1.2.17
  org.jboss.logging:jboss-logging: 3.1.2.GA, 3.2.1.Final
  org.slf4j:slf4j-api: 1.7.2, 1.7.25

好的,我知道了。问题是 RoleConverter 转换为 ceylon.language.String,而 api 期望转换为 java.lang.String。现已修复:

shared class RoleConverter() extends Converter<Role, JString>() {
    shared actual Role doBackward(JString? name) {
        "Cannot convert null to role."
        assert (exists name);
        return Role.ofName(name.string);
    }

    shared actual JString doForward(Role? role) {
        return JString(role?.name else "null");
    }
}