Katalon Cucumber - Picocontainer - Dependency Injection

I am trying to configure Katalon Cucumber to share test state (scenario context) between step definitions with dependency injection via the cucumber-picocontainer dependency. This is something I’ve done before with Maven and Java Cucumber. Katalon uses Gradle and the configuration is different.

I found this site.

I executed this command.
gradle katalonCopyDependencies

I received this error.
Could not find method compile() for arguments [io.cucumber:cucumber-picocontainer:7.0.0] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

Here is the build.gradle file.
plugins {
id ‘java’
id “com.katalon.gradle-plugin” version “0.0.7”
}
repositories {
mavenCentral()
}
dependencies {
compile ‘io.cucumber:cucumber-picocontainer:7.0.0’
}

When executing the test case in Katalon Studio, this error occurs.
Test Cases/Sample-Cucumber FAILED.
Reason:
com.kms.katalon.core.exception.StepFailedException: These following reason:
[class steps.SampleSteps doesn’t have an empty constructor. If you need DI, put cucumber-picocontainer on the classpath, class steps.SampleSteps doesn’t have an empty constructor. If you need DI, put cucumber-picocontainer on the classpath]

Thank you.

@mike.duncan.ctr

Please use Gradle 6.x instead Gradle 7.0+

I am using Gradle 6.

This is the build.gradle file.

plugins {
id ‘java’
id “com.katalon.gradle-plugin” version “0.1.1”
}

repositories {
mavenCentral()
}

dependencies {
compile ‘io.cucumber:cucumber-picocontainer:7.0.0’
}

This command is executed.

gradle katalonCopyDependencies

This is the error that occurs.

FAILURE: Build failed with an exception.

  • Where:
    Build file ‘C:\dev\katalon\nitaac-neos-rfx-katalon\build.gradle’ line: 3

  • What went wrong:
    Plugin [id: ‘com.katalon.gradle-plugin’, version: ‘0.1.1’] was not found in any of the following sources:

  • Gradle Core Plugins (plugin is not in ‘org.gradle’ namespace)
  • Plugin Repositories (could not resolve plugin artifact ‘com.katalon.gradle-plugin:com.katalon.gradle-plugin.gradle.plugin:0.1.1’)
    Searched in the following repositories:
    Gradle Central Plugin Repository

I tried to reproduce what @mike.duncan.ctr reported. The build.gradle is as follows:

plugins {
id "java"
id "com.katalon.gradle-plugin" version "0.1.1"
}

repositories {
mavenCentral()
}

dependencies {
compile "io.cucumber:cucumber-picocontainer:7.0.0"
}

I ran it wit Gradle 6, and got error:

$ gradle katalonCopyDependencies

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/kazuakiurayama/katalon-workspace/test/build.gradle' line: 3

* What went wrong:
An exception occurred applying plugin request [id: 'com.katalon.gradle-plugin', version: '0.1.1']
> Failed to apply plugin class 'com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin'.
   > This version of Shadow supports Gradle 7.0+ only. Please upgrade.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 24s
:~/katalon-workspace/test (master *)
$ gradle --version

------------------------------------------------------------
Gradle 6.9.1
------------------------------------------------------------

Build time:   2021-08-20 11:15:18 UTC
Revision:     f0ddb54aaae0e44f0a7209c3c0274d506ea742a0

Kotlin:       1.4.20
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          1.8.0_322 (Amazon.com Inc. 25.322-b06)
OS:           Mac OS X 12.2.1 x86_64

The message says:

This version of Shadow supports Gradle 7.0+ only. Please upgrade.

@duyluong wrote that the com.katalon.gradle-plugin requires Gradle 6, but its dependent module “Shadow” requires Gradle7.0+.

Here is a unresolvable conflit.

I suppose, the com.katalon.gradle-plugin is no longer operational.

@duyluong

The only way to resolve this contradiction for Katalon Team would be to update their plugin operational on Gradle 7.0+.

Try edit the build.gradle as follows

ext {
    AUTO_IMPORTED_JAR_PREFIX = 'AUTOIMPORTED_'
}

repositories {
    mavenCentral()
}

configurations {
    myconf
}

dependencies {
    myconf "io.cucumber:cucumber-picocontainer:7.0.0"
}

task drivers {
    doFirst {
        delete fileTree("Drivers") {
            include("**/" + AUTO_IMPORTED_JAR_PREFIX + "*")
        }
    }
    doLast {
        copy { copySpec ->
            copySpec
                .from(project.getConfigurations().getByName("myconf"))
                .into("Drivers")
                .include(
                    "**/cucumber-picocontainer*.jar"
                )
                .rename({ s ->
                    AUTO_IMPORTED_JAR_PREFIX + s
                })
        }
    }
}

and run

> gradle drivers

This will work with both Gradle 6 and Gradle 7+.

gradle drivers will downloaded the jar and located into the projects Drivers folder. You fill find

$ ls Drivers
AUTOIMPORTED_cucumber-picocontainer-7.0.0.jar

Once I have ever studied the source of com.katalon.gradle-plugin v0.0.7. I found that it does the following processing steps:

  1. download the specified jar io.cucumber:cucumber-picocontainer:7.0.0 into a folder managed by Gradle
  2. also download the other jars which the specified jar (picocontainer:7.0.0) depends upon
  3. create a “Fat Jar” which contains all files in the jars downloaded at #1 and #2
  4. place the Fat Jar into the Drivers folder of the Katalon project.

What is “Fat Jar”? — see https://imperceptiblethoughts.com/shadow/introduction/#benefits-of-shadow

On the other hand, my build.gradle does

  1. download the specified jar io.cucumber:cucumber-picocontainer:7.0.0 into a folder managed by Gradle
  2. also download the other jars which the specified jar (picocontainer:7.0.0) depends upon
  3. (no, it doesn’t)
  4. (no, it doesn’t)
  5. select and copy only the specified jar into Drivers folder while renaming the file name with AUTOIMPORTED_ prefix.

Using my build.gradle, the Drivers/AUTOIMPORTED_io.cucumber.picocontainer-7.0.0.jar will stand alone without its dependencies. Consequently Katalon Studio will look for the depending classes in its original classpath. As you know, Katalon Studio bundles the cucumber jars of older version. Therefore it is highly likely that you would encounter more problems caused by version-conflict in the classpath.

@mike.duncan.ctr

Please try my build.gradle and see what happens…

@kazurayam @mike.duncan.ctr

With the new version com.katalon.gradle-plugin v0.1.1 onward, we need to use with Gradle v7.0+. Please refer to our latest guide: https://github.com/katalon-studio/katalon-gradle-plugin#tutorial-automatically-download-dependencies-for-katalon-studio-projects

With com.katalon.gradle-plugin v0.0.7 or lower versions, we need to use with Gradle v5.x or v6.x

I switched to Gradle 7

$ gradle --version

------------------------------------------------------------
Gradle 7.4.2
------------------------------------------------------------

Build time:   2022-03-31 15:25:29 UTC
Revision:     540473b8118064efcc264694cbcaa4b677f61041

Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          1.8.0_322 (Amazon.com Inc. 25.322-b06)
OS:           Mac OS X 12.2.1 x86_64

I tried the following build.gradle

plugins {
    id "com.katalon.gradle-plugin" version "0.1.1"
}

repositories {
    mavenCentral()
}

dependencies {
    runtimeClasspath "io.cucumber:cucumber-picocontainer:7.2.3"
}

I ran the following command

$ gradle katalonCopyDependencies

I got a few jars in the Drivers folder

$ ls Drivers
katalon_generated_apiguardian-api-1.1.2.jar
katalon_generated_ci-environment-8.1.0.jar
katalon_generated_cucumber-core-7.2.3.jar
katalon_generated_cucumber-expressions-15.0.1.jar
katalon_generated_cucumber-gherkin-7.2.3.jar
katalon_generated_cucumber-gherkin-messages-7.2.3.jar
katalon_generated_cucumber-picocontainer-7.2.3.jar
katalon_generated_cucumber-plugin-7.2.3.jar
katalon_generated_datatable-7.2.3.jar
katalon_generated_docstring-7.2.3.jar
katalon_generated_html-formatter-17.0.0.jar
katalon_generated_messages-17.1.1.jar
katalon_generated_picocontainer-2.15.jar
katalon_generated_tag-expressions-4.1.0.jar

I got the required jars copied into the “Drivers” folder successfully.

(However, these jars are not “Fat”. It seems that the plugin v0.1.1 no longer uses Shadow JAR)

I have a doubt. As far as I see in the .classpath file the new cucumber-core-7.2.3.jar in the “Drivers” folder has lower precedece that the old cucumber-core_3.0.2.jar which is bundled in the Katalon Studio v8.2.5 ZIP.

The precedence rule is simple. The cucumber-core_3.0.2.jar appears first at the line#126, the cucumber-core_7.2.3.jar appears later at the line #163. The jar that appears first in the list of <classpathentry> tags in the .classpath file has the precedence.

Therefore the newer version of cucumber-core will not be used by Katalon Studio; Katalon Studio will use the older version of cucumber-core.

@mike.duncan.ctr

I suppose you will get a bunch of version conflicts when you try to use the picocontainer.

Katalon offers a way to try to workaround version conflicts for yourself by excluding the older version of cucumber jars by following the instruction at

However please find that they wrote

  • io.cucumber.*.jar
    Excluding those libraries may cause failure of the relevant features.

If you try to exclude cucumber-core_3.0.2.jar then I am afraid you might get a serious failure in KS. I can not predict what will happen. I suppose that the only favourable resolution for @mike.duncan.ctr would be Katalon Team works and upgrades the version of io.cucumber library bundled in KS to the recent versions (v7.2.3 for example).

You may want to go back there.

The latest version of io.cucumber is 7.2.3 while Katalon Studio bundles io.cucumber of v3.0.2, which is 4 years old. Obviously Katalon team does not keep their products in sync with the recent development of Cucumber project. Perhaps they are no longer keen on supporting Cucumber. So, in my humble opinion, people who want to use the latest Cucumber features had better not use KS.

Users MUST declare dependendencie with the runtimeClasspath role. I found this fact by reading the source.

WARNING: Katalon’s documentation DOES NOT explain this at all.

If a user write

testImplementation "io.cucumber:cucumber-picocontainer:7.2.3"

the plugin passes but puts no jar files in the Drivers directory.

And if a user write

implementation "io.cucumber:cucumber-picocontainer:7.2.3"

the plugin passes does nothing either.

2 Likes

Thanks a lot for this post @kazurayam. Picco was not working because I was in version 7.5.0. By downgradding it to 3.0.2 it does work correctly :+1:

Honestly, I don’t understand how Katalon still use a more than 4year old version of cucumber…

In any Katalon Studio project, you have a file named .classpath. In a .classpath file created by Katalon Studio ver8.x, I found a line:

<classpathentry kind="lib" path="/Applications/Katalon Studio.app/Contents/Eclipse/plugins/io.cucumber.core_3.0.2.jar"/>

This proves that Katalon Studio bundled the io.cucumber.core_3.0.2.jar in its ZIP distributable. Katalon uses it for its own sake (for its own Cucumber support) which was developed 4years ago.

… because Katalon Studio’s old code uses the old version of io.cucumber.core, and stays unchanged. Therefore they do not need to upgrade the io.cucumber.core jar to any newer versions.

If you want to add a jar of io.cucumber:cucumber-picocontainer, you should choose a version that works in sync with the io.cucumber.core_3.0.2.jar. If you included any different version such as “io.cucumber:cucumber-picocontainer:7.2.3”, you would have troubles.

1 Like