jfrog / artifactory-gradle-plugin

JFrog Gradle plugin for Build Info extraction and Artifactory publishing.
Apache License 2.0
21 stars 15 forks source link

Cannot access class 'org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration' #44

Closed tomfi closed 1 year ago

tomfi commented 1 year ago

Describe the bug

I'm upgrading from v4 to v5, my setup looks like the following (omitting some internal things):

buildSrc/build.gradle.kts

import java.util.Properties

plugins {
  `kotlin-dsl`
}

repositories {
  mavenCentral()
  mavenLocal()
  gradlePluginPortal()
}

Properties().apply {
  val props = this
  rootDir.toPath().resolveSibling(Project.GRADLE_PROPERTIES).toFile().apply {
    val file = this
    file.inputStream().use {
      props.load(it)
    }
  }
}.forEach { key, value -> project.extra.set(key as String, value) }

dependencies {
  ...
  val artifactoryGradlePluginVerison: String by project
  implementation("org.jfrog.buildinfo:build-info-extractor-gradle:$artifactoryGradlePluginVerison")
}

Than in a convention: buildSrc/src/main/kotlin/foo.conventions.gradle.kts

plugins {
  ...
  id("com.jfrog.artifactory")
}

...

configure<org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention> {
  // general
  clientConfig.isIncludeEnvVars = true
  clientConfig.envVarsExcludePatterns = "*password*,*secret*,*key*,*token*,*passphrase*"
  clientConfig.timeout = 3600

  // publisher
  clientConfig.publisher.isMaven = true
  clientConfig.publisher.username = artifactoryUsername
  clientConfig.publisher.password = artifactoryPassword
  clientConfig.publisher.repoKey = "..."

  // build info
  clientConfig.info.buildName = artifactoryBuildName
  clientConfig.info.buildNumber = buildNumber

  publish {
    contextUrl = "..."
    defaults {
      publications("ALL_PUBLICATIONS")
      setProperties(
        mapOf(
          "build.name" to artifactoryBuildName,
          "build.number" to buildNumber,
        )
      )
    }
  }
}

When trying to build, I'm getting:

e: file:///... Cannot access class 'org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration'. Check your module classpath for missing or conflicting dependencies

After digging a bit, i found that you import dependencies in your repositories using implementation(...), this makes the internal libraries you import not accesibble for people that import your plugins (see api(...) and implementation(...) in gradle https://stackoverflow.com/questions/44413952/gradle-implementation-vs-api-configuration)

After importing your transative libraries manually:

  implementation("org.jfrog.buildinfo:build-info-extractor:2.39.8")
  implementation("org.jfrog.buildinfo:build-info-client:2.39.8")

It works as expected.

Please change the scope of your imports to api instead of implementation so the plugin/library will work as expected without workarounds

Current behavior

Using the plugin as-is does not allow to use transitive jfrog dependencies without explicitly stating them in the build

Reproduction steps

See details in the description. create a project, use the plugin, try to access classes that should arrive transitively, get an exception

Expected behavior

Transitive libraries that should be exposed to the consumer should be imported with api scope instead of implementation scope so consumers can set properties on those classes (like shown in the documentation)

Artifactory Gradle plugin version

5.0.3

Operating system type and version

macOS 13.3

JFrog Artifactory version

cloud

Gradle version

8.2.1

yahavi commented 1 year ago

Hello @tomfi,

Thank you for making use of the Gradle Artifactory plugin. I observed that you imported the plugin using "implementation" instead of the recommended Gradle approach:

plugins {
    id "com.jfrog.artifactory" version "5.+"
}

Could you please clarify if there is a specific reason for using the plugin in this manner?

tomfi commented 1 year ago

@yahavi it does not affect the issue, i also tried importing using the recommended way.

The reason i import it as i do is because I have a more complex setup than the default (multi-module, with conventions) and im importing the artifactory plugin inside the convention. In order for it to work based on gradle docs and a lot of trial-and-error the way to import plugins in this case is via implementation/api inside the buildSrc and if you would see the convention part it would look like you mentiond.

Also inside the convention if you try to specify the version gradle would not compile.

In any case, you can reproduce the issue I mentioned in a normal, not complex, project using any import method.

tomfi commented 1 year ago

@yahavi any other info you need about the issue?

it will prevent advanced usage of the plugin

yahavi commented 1 year ago

Understood, @tomfi.

I merged the code. Once again, thank you.

tomfi commented 1 year ago

@yahavi thank you :)