I am trying to update a project that uses Groovy's Cucumber implementation. I am getting the following error when trying to run:
./gradlew cucumber -Denv=test -Ptags=#myTest --continue --no-daemon
Error: Could not find or load main class io.cucumber.core.cli.Main
Caused by: java.lang.ClassNotFoundException: io.cucumber.core.cli.Main
I see the relevant dependency locally
and from my IntelliJ Run Configuration, I am able to set the Main class:io.cucumber.core.cli.Main with no errors. Yet when I run from this context, it gives me undefined step definition errors, despite being able to click through to the Step Defs from the feature files.
I am using Gradle (from wrapper context) 5.0
The section that declares the jar in the cucumber task in the build.gradle is:
doLast {
javaexec {
main = "io.cucumber.core.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
systemProperty "parallel", System.properties.getProperty("parallel", setParallel)
if (setParallel == "true") cucumberArgs.addAll(cucumberThreadsOption)
args = cucumberArgs
jvmArgs = [
"-Denv=$env",
]
}
}
My dependencies:
dependencies {
implementation "io.cucumber:cucumber-core:5.1.3"
implementation "io.cucumber:cucumber-groovy:5.1.3"
compile "org.codehaus.groovy:groovy-all:2.5.6"
}
Wonder if there is anything obvious?
Related
I use vscode and gradle to build my java jar. In the project I import com.google.gson.Gson and can create an object of Gson. If I run the code everything works fine, but if I use gradlew build to create the jar and when I try to executed the jar file then I get this Error: "Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/GsonBuilder"
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
// This dependency is used by the application.
implementation 'com.google.guava:guava:30.1.1-jre'
implementation 'com.google.code.gson:gson:2.10'
}
jar {
manifest {
attributes(
'Main-Class': 'analyser.Run'
)
} }
I do not understand what is wrong here. Any ideas?
I had a mistake in the build.gradle, now it works by using
plugins {
id 'java'
id 'application'
id 'distribution'
}
I have a module which uses Groovy (2.5.14) and Scala (2.11.6). All the dependencies are maintained by gradle (ver 6.x). While building the project I am getting some strange compilation Error as shown below:
[Error] Class A.B.C$Trait$FieldHelper not found - continuing with a stub.
(where C is some trait)
To be precise, while build the module, the task compileTestScala fails with the above error.
Here is the snapshot of the build gradle
compileTestScala {
classpath = classpath.plus(files(compileTestGroovy.destinationDir))
dependsOn compileTestGroovy
}
compileScala {
classpath = classpath.plus(files(compileGroovy.destinationDir))
dependsOn compileGroovy
}
However, the compileScala builds successfully. What could be the root cause?
The background to this is as follows.
I need to run some tests (let's call it TestClass) that are annotated as #SpringBootTest and are JUnit tests
The TestClass is invoked by a runner in TestScript.groovy (which is a Groovy script)
This TestScript collates all the tests results
In order to do this, I created the following build.gradle file:
apply plugin: 'org.springframework.boot'
apply plugin: 'org.spring.dependency-management'
apply plugin: 'groovy'
sourceSets {
test {
groovy {
srcDirs = 'src/test'
}
}
}
test {
exclude 'com/domain/test/**' // This is to avoid this task running any of the tests without TestScript.groovy
}
task runtest(type: JavaExec) {
dependsOn test // because test task builds from source
args '-env', 'test' // program arguments
main 'com.domain.test.TestScript'
jvmArgs ['spring.profiles.active=test']
classpath configuration.compile, configurations.runtime, sourceSets.test.output, sourceSets.main.output, configurations.compileClasspath, configurations.runtimeClasspath
}
The project file structure is as follows:
project-root
src
main
java
com
domain
SomeClass.java // These are needed for the JUnit tests
test
java
com
domain
test
TestScript.groovy
TestClass.java
The main issue is that TestScript.groovy when calling TestClass.java is ignoring SpringBootTest. Instead it just runs the test method without Spring Boot, and of course no dependency injection occurs so the test fails with null pointer exceptions.
So to execute this, at the command line I type:
$ ./gradlew clean runtest
Now, I know you should be able to do this, because IntelliJ will run this setup just fine. However, I'm unable to decipher what they really did (even after studying the incredibly long command they run on the command line).
Anyone have any suggestions on how to make this work as I'm 3-4 days out of solutions?
I'm trying to create and run an executable jar through gradle. This is what my current gradle looks like:
task jarTask(type: Jar) {
baseName = 'my-main-class'
from 'build/classes/main'
}
task createJarWithDependencies(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Sample Jar',
'Implementation-Version': 1,
'Main-Class':'com.example.MyMainClass'
}
baseName = "my-main-class-with-dependencies"
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jarTask
}
configurations {
jarConfiguration
}
artifacts {
jarConfiguration jarTask
}
// This is the task that I call with ./gradlew to execute my jar
task runMyJar(type: JavaExec) {
classpath files('build/libs/my-main-class-with-dependencies.jar')
main 'com.example.MyMainClass'
args = ["param1","param2"]
outputs.upToDateWhen { false }
}
runMyJar.dependsOn(createJarWithDependencies, build)
I got these approach from the following stack overflow answers/references below:
Android Studio export jar with dependencies
Android studio - How to use an executable jar file from gradle
However when I run ./gradlew clean runMyJar (or even just ./gradlew runMyJar, I get the following error message:
Error: Could not find or load main class com.example.MyMainClass
Can anyone point out the reason why my executable jar is not finding the main method inside my class? Is there anything I'm missing?
Since I haven't had much luck with this solution, I managed to get around this problem by doing the following instead:
task deleteJar(type: Delete) {
delete 'libs/my-main-class.jar'
}
task createJar(type: Copy) {
from('build/intermediates/bundles/debug/')
into('libs/')
include('classes.jar')
rename('classes.jar', 'my-main-class.jar')
}
// This is the task that I call with ./gradlew to execute my jar
task runMyJar(type: JavaExec) {
classpath files('libs/my-main-class.jar')
classpath files('libs/common-util.jar')
main 'com.example.MyMainClass'
args = ["param1","param2"]
outputs.upToDateWhen { false }
}
createJar.dependsOn(deleteJar, build)
runMyJar.dependsOn(createJar, build)
This is not the solution that I want though, since this approach doesn't pull in the dependencies from other modules referenced by this module, which is what I was trying to solve. In order to do that, what I end up doing is copy/paste this same approach on those "other" modules and generate a lib for that module, and then copy that lib over to the libs folder of this module. OR I can move those dependent code in this same module so I don't have to deal with it. For a simple application that's not too bad (which, luckily, is my situation), but for a complex one, I'm not sure how to go about that.
As an added reference here is my dependencies section:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':common-util')
// common-util is an Android module, which references other Android
// methods such as Log.d, android.util class methods, etc.
}
By the way, I'm using the Android Studio IntelliJ IDE for this (which was the original motivation of my post). My hope was to not have to create separate jars from other modules to include it to this module but instead do it all in one go ...
Currently I have the following build.gradle file:
apply plugin: 'java'
sourceSets {
main {
java {
srcDir 'src/model'
}
}
}
dependencies {
compile files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
}
This build.gradle file is for my repository here. All of my main files are in src/model/ and their respective tests are in test/model.
How do I add a JUnit 4 dependency correctly and then run those tests in the folders of tests/model?
How do I add a junit 4 dependency correctly?
Assuming you're resolving against a standard Maven (or equivalent) repo:
dependencies {
...
testCompile "junit:junit:4.11" // Or whatever version
}
Run those tests in the folders of tests/model?
You define your test source set the same way:
sourceSets {
...
test {
java {
srcDirs = ["test/model"] // Note #Peter's comment below
}
}
}
Then invoke the tests as:
./gradlew test
EDIT: If you are using JUnit 5 instead, there are more steps to complete, you should follow this tutorial.
If you set up your project with the default gradle package structure, i.e.:
src/main/java
src/main/resources
src/test/java
src/test/resources
then you won't need to modify sourceSets to run your tests. Gradle will figure out that your test classes and resources are in src/test. You can then run as Oliver says above. One thing to note: Be careful when setting property files and running your test classes with both gradle and you IDE. I use Eclipse, and when running JUnit from it, Eclipse chooses one classpath (the bin directory) whereas gradle chooses another (the build directory). This can lead to confusion if you edit a resource file, and don't see your change reflected at test runtime.
If you created your project with Spring Initializr, everything should be configured correctly and all you need to do is run...
./gradlew clean test --info
Use --info if you want to see test output.
Use clean if you want to re-run tests that have already passed since the last change.
Dependencies required in build.gradle for testing in Spring Boot...
dependencies {
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
For some reason the test runner doesn't tell you this, but it produces an HTML report in build/reports/tests/test/index.html.
This is for Kotlin DSL (build.gradle.kts) and using JUnit 5 (JUnit platform):
tasks.test {
// Discover and execute JUnit4-based tests
useJUnit()
// Discover and execute TestNG-based tests
useTestNG()
// Discover and execute JUnit Platform-based (JUnit 5, JUnit Jupiter) tests
// Note that JUnit 5 has the ability to execute JUnit 4 tests as well
useJUnitPlatform()
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.8.2")
// ...
}
testCompile is deprecated. Gradle 7 compatible:
dependencies {
...
testImplementation 'junit:junit:4.13'
}
and if you use the default folder structure (src/test/java/...) the test section is simply:
test {
useJUnit()
}
Finally:
gradlew clean test
Alos see: https://docs.gradle.org/current/userguide/java_testing.html
If you want to add a sourceSet for testing in addition to all the existing ones, within a module regardless of the active flavor:
sourceSets {
test {
java.srcDirs += [
'src/customDir/test/kotlin'
]
print(java.srcDirs) // Clean
}
}
Pay attention to the operator += and if you want to run integration tests change test to androidTest.
GL