pdvrieze / xmlutil

XML Serialization library for Kotlin

Home Page:https://pdvrieze.github.io/xmlutil/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't be used from pure Java code

StefanOltmann opened this issue · comments

On https://github.com/StefanOltmann/xmpcore-java-sample I build a sample project to show how https://github.com/Ashampoo/xmpcore can be used from a Java project (using Temurin 17.0.10+7).

It looks like there are missing declarations to make it work.

Used from a Kotlin multiplatform project (https://github.com/Ashampoo/kim in this case) there is no issue.

I want to provide Java users an alternative to Adobe XMP Core. So it would be really nice to have it working in a Java environment.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
   > Could not resolve io.github.pdvrieze.xmlutil:core:0.86.3.
     Required by:
         project : > com.ashampoo:xmpcore:1.2.1 > com.ashampoo:xmpcore-jvm:1.2.1
      > The consumer was configured to find a library for use during compile-time, compatible with Java 17, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally. However we cannot choose between the following variants of io.github.pdvrieze.xmlutil:core:0.86.3:
          - androidApiElements-published
          - jvmApiElements-published
        All of them match the consumer attributes:
          - Variant 'androidApiElements-published' capability io.github.pdvrieze.xmlutil:core:0.86.3 declares a library for use during compile-time, packaged as a jar:
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 17)
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'jvmApiElements-published' capability io.github.pdvrieze.xmlutil:core:0.86.3 declares a library for use during compile-time, packaged as a jar:
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 17)
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
   > Could not resolve io.github.pdvrieze.xmlutil:serialization:0.86.3.
     Required by:
         project : > com.ashampoo:xmpcore:1.2.1 > com.ashampoo:xmpcore-jvm:1.2.1
      > The consumer was configured to find a library for use during compile-time, compatible with Java 17, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally. However we cannot choose between the following variants of io.github.pdvrieze.xmlutil:serialization:0.86.3:
          - androidApiElements-published
          - jvmApiElements-published
        All of them match the consumer attributes:
          - Variant 'androidApiElements-published' capability io.github.pdvrieze.xmlutil:serialization:0.86.3 declares a library for use during compile-time, packaged as a jar:
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 17)
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'jvmApiElements-published' capability io.github.pdvrieze.xmlutil:serialization:0.86.3 declares a library for use during compile-time, packaged as a jar:
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 17)
                  - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it

Ah, the issue is the "automatic" use of attributes to use variants. I'll need to fix this as it isn't going to be supported by the kotlin plugin anymore. What I can do is provide you with some gradle code to create the attribute and an appropriate resolution strategy. Alternatively you could manually add core-jvm and exclude the platform independent version from being included.

What I can do is provide you with some gradle code to create the attribute and an appropriate resolution strategy.

That would be great! :)

I'll have to deal with this anyway as the kotlin plugin architecture has changed for this. In the meantime there are two options:

  • exclude the core module and inject core-jvm
  • manually create the 'org.jetbrains.kotlin.platform.type' property and set it to 'jvm'

I'm not sure how to do that. :/

This way is wrong:
Ashampoo/xmpcore@main...java_fix

What you do is exclude core from the xmlutil-serialization dependency (and add core-jvm) instead. I'm working on the needed multi-project setup needed for the new design.

In that commit I removed serialization as I figured out that I’m not actually using it (anymore).

The problem here is that this structure in the branch adds core twice.

I guess I would need to try that 'org.jetbrains.kotlin.platform.type' property instead, but I don’t know where to set that.

To be honest I don’t understand how the architecture works. I copied from a template and was glad that it worked.

@StefanOltmann The easiest is to add the kotlin plugin to the classpath (but not apply it) as that has the correct attributes in the context.

The attribute is created using (you can use String instead of KotlinPlatformType:

Attribute.of(
            "org.jetbrains.kotlin.platform.type",
            KotlinPlatformType::class.java
        )

KotlinPlatformType has the following possible values: "common", "jvm", "js", "androidJvm", "native", "wasm".

Then in the attributes extension of your configuration have the following (or the string equivalent):

attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)

See also:

xmlutil/build.gradle.kts

Lines 133 to 138 in 7df6df3

extensions.findByType<KotlinJvmProjectExtension>()?.run {
target {
attributes {
attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, envJvm)
attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
}

That sets the attribute for a kotlin jvm project. (It also sets the attribute for the gradle target environment attribute – I'm not sure why it doesn't work, but it may be that gradle doesn't quite have a resolution strategy). You may try that one as that doesn't require the kotlin plugin at all (but still allows you to reuse the attribute rather than creating a new one).

Thank you for your explanation.

I tried to copy from your mentioned configuration, but I was not able to get it to work.

https://github.com/Ashampoo/xmpcore/blob/b19711926cf86f80eda868cfbb186a7a84315c25/build.gradle.kts#L469-L493

I guess I'll need to wait until you figure it out and provide a fixed version.

I made it work in your java project by doing the following (in the build.gradle.kts file in the root):

dependencies {
    implementation("com.ashampoo:xmpcore:1.2.1") {
        exclude("io.github.pdvrieze.xmlutil", "core")
        exclude("io.github.pdvrieze.xmlutil", "serialization")
    }
    implementation("io.github.pdvrieze.xmlutil:serialization-jvm:0.86.3") {
        exclude("io.github.pdvrieze.xmlutil", "core")
    }
    implementation("io.github.pdvrieze.xmlutil:core-jvm:0.86.3")
}

Alternatively, you can use attributes:

val platformAttr = Attribute.of("org.jetbrains.kotlin.platform.type",String::class.java)

configurations.all {
    attributes {
        attribute(platformAttr, "jvm")
    }
}

Thank you a lot! I did go with the second approach.

I did not understand that I needed to add it to the Java sample. I was thinking there is something I could add to the main project that it will work without such a workaround instruction. ^^

For me that solution is sufficient. Thanks again!

The problem is that gradle doesn't know which version to match as the consumer has no attached attributes (nor is one attached to the dependency). But the current approach isn't great. I may need to put in an adjustment to the generated module specifications.