Weird `java.lang.NoSuchMethodError` that pops up when trying to use GMail API with Katalon Studio

It’s a shame that this Katalon Studio plugin doesn’t work to fetch new messages on threads containing multiple messages.

For example, if you have some Message1 that is the latest message, the API gets it just fine. However, when you, for example, click on the link contained therein, to some form, fill out that form, and the system under test sends some Message2 on that same thread, containing another important link…

…and no other messages are sent to the test email except that one…

…the API only returns the Message1 when you ask it for the latest message.

:cry: ToT

Damn, do I have to whip out another solution? The only one I can think of, is Google’s Gmail API for Java…and that is…complex to set up (we’re talking not just setting up the 2fa and authorizing your program)…

I grit my teeth, follow this quickstart verbatim, including their source code (the fun part, because I swap their main() out for some public static List<String> GetLabels())…

create some test:

WebUI.verifyNotEqual(GmailQuickstart.GetLabels().size(), 0)

run that test…

…and I face this Error:

Test Cases/Unit Tests/SMDEmailUtils FAILED.
Reason:
java.lang.NoSuchMethodError: com.google.api.client.http.HttpTransport.isMtls()Z
	at com.google.api.services.gmail.Gmail$Builder.chooseEndpoint(Gmail.java:11179)
	at com.google.api.services.gmail.Gmail$Builder.<init>(Gmail.java:11212)
	at com.signaturemd.utils.GmailQuickstart.GetLabels(GmailQuickstart.groovy:73)
	at com.signaturemd.utils.GmailQuickstart$GetLabels.call(Unknown Source)
	at SMDEmailUtils.run(SMDEmailUtils:6)
	at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
	at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
	at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:448)
	at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:439)

I try piddling around with the dependencies in my build.gradle file, but nothing seem to work to resolve it. I even suspect that some transitive google-http-client dependency may be to blame, so I add:

configurations.all { 
  resolutionStrategy.force 'com.google.http-client:google-http-client:1.42.1'
}

It doesn’t work.

I try to re-produce the Error in vanilla Java Eclipse project. I dust off my Eclipse developer skills…

…download Eclipse…

…set up Gradle on Eclipse…

…copy the GmailQuickstart over to the Eclipse project…

…write same test, in JUnit, against that GmailQuickstart method…

…run it…

…and I don’t face the Error! Test passes!

How can this be when my Katalon build.gradle looks like:

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

repositories {
  mavenCentral()
}

dependencies {

  implementation 'com.github.javafaker:javafaker:1.0.2'
  
  implementation 'com.google.api-client:google-api-client:2.0.0'
    
  implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
    
  implementation 'com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0'
}

configurations.all { 
  resolutionStrategy.force 'com.google.http-client:google-http-client:1.42.1'
}

and the Eclipse MVCE project build.gradle looks like this:

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java library project to get you started.
 * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
 * User Manual available at https://docs.gradle.org/7.4.2/userguide/building_java_projects.html
 */

plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id "com.katalon.gradle-plugin" version "0.1.1"
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'

    // This dependency is exported to consumers, that is to say found on their compile classpath.
    api 'org.apache.commons:commons-math3:3.6.1'

    // This dependency is used internally, and not exposed to consumers on their own compile classpath.
    implementation 'com.google.guava:guava:30.1.1-jre'
	
    implementation 'com.github.javafaker:javafaker:1.0.2'
	
//	Gmail API dependencies
	implementation 'com.google.api-client:google-api-client:2.0.0'
	
	implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
    
    implementation 'com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0'
}

tasks.named('test') {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}


  
configurations.all {
	resolutionStrategy.force 'com.google.http-client:google-http-client:1.42.1'
}

?

Hi chị Jass, could you take a look at this? Thanks chị

Whats the status on this bug?

In my own Katalon Studio project, it has <projectDir>/.classpath file. In that file I found a line as follows:

	<classpathentry kind="lib" 
path="/Applications/Katalon Studio.app/Contents/Eclipse/plugins/com.google.http-client.google-http-client_1.22.0.jar"/>

This implies that Katalon Studio v8.3.0 bundles the com.google.http-client_1.22.0.jar. The bundled jar files will have higher precendence over the jars which you added in the <projectDir>/Drivers directory.

@mwarren04011990

Even if you prepared the newer version of com.google.http-client:google-http-client:1.42.1 or 2.0.0, these will not be used by Katalon Studio.

Why?

Katalon Studio will look up a class in the jar files listed in the .classpath file; the jar that comes first in the .classpath file wins the other jars that comes later. And the jars you added in the Drivers will be listed at the end of the .classpath file.

The following document explains how to exclude built-in libraries.

You can setup Katalon Studio to ignore the built in version of com.google.http-client.google-http-client_1.22.0.jar, and prefer the jar you located in the Drivers dir.

This will effectively change the .classpath slightly. The bundled version of jar will be removed out of the .classpath file. Then Katalon Studio will fall down to the jars in the Drivers dir to look for a class.