I am using Gradle build in my java application. My project has the elasticsearch intergation test. Following is my gradle.build
jar {
baseName = 'myproject'
version = 'V.4.0.0'
manifest {
attributes 'Main-Class': 'com.myapp.Application'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
test {
systemProperties = System.properties
systemProperty 'tests.security.manager', 'false'
}
When i give gradle build it executed the test and created the myproject-V.4.0.0.jar. but when i run the
java -cp myproject-V.4.0.0.jar;junit-4.11.jar junit.textui.TestRunner com.myapp.test.testclassname
i got class not found exception for com.myapplication.test.testclassname.
I extracted the myproject-V.4.0.0.jar and can not find the test class.
My question is, How can i include the test class also in my application jar?
This is a deliberate behaviour of gradle java projects. A jar is your production artifact, so usually you want to test it during the build, but you do not want to run your tests in production, so I do not recommend doing it. Having said that, there is a way of doing it in gradle, like this:
task myJar(type:Jar) {
from {sourceSets.main.output + sourceSets.test.output}
}
Related
I have a compiled jar with JUnit tests that I want to run from a docker container.
I want to do it with a Gradle task.
First, I will compile the jar and copy it with all its dependencies to a Gradle-based image.
(Or I can create a fat jar which will contain all the third party compiled to a .class).
Then I want to run the task - this task will only run tests according to a test name, JUnit tag, etc.
Is it possible to run a Gradle task on a compiled jar without having its sources?
What should I include in this image beside the gradle.build file for it to work?
Thank you
Gradle fetch transitive dependencies and run its tests in test process by default, so you can use this feature in your case.
Note that abstract classes are not executed. In addition, be aware that Gradle scans up the inheritance tree into jar files on the test classpath. So if those JARs contain test classes, they will also be run.
Gradle tests detection document.
Here is how to do it in your case :
Create an empty Gradle project and apply the java plugin.
import the test dependencies tools with the needed scopes in the dependencies section.
import myApp.jar as a local dependency.
Configure the test task (add needed properties and args).
Run Gradle test with the specific properties.
build.gradle example :
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
// just examples change with needed unit tests dependencies
testImplementation('org.junit.jupiter:junit-jupiter-api:5.4.2')
testRuntime('org.junit.jupiter:junit-jupiter-engine:5.4.2')
// the target jar file
compile file("/myApp.jar")
}
project.ext.testName = project.hasProperty("testName") ?
project.property("testName") : "*"
test {
useJUnitPlatform()
filter {
//include specific method in any of the tests
includeTestsMatching "$testName"
}
}
Now the Gradle test command will run the target tests in myApp.jar.
For more information about it check the Testing in Java & JVM projects official Gradle documents
I have a simple groovy script with a single java library dependency:
package com.mrhacki.myApp
import me.tongfei.progressbar.ProgressBar
class Loading {
static void main(String[] arguments) {
List list = ["file1", "file2", "file3"]
for (String x : ProgressBar.wrap(list, "TaskName")) {
println(x)
}
}
}
I'm using gradle to manage the dependencies of the project. The gradle configuration for the project is pretty straightforward too:
plugins {
id 'groovy'
}
group 'com.mrhacki'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
compile 'me.tongfei:progressbar:0.7.2'
}
If I run the script from the Intellij IDE, the script is executed as expected.
What I would like to do now is to compile the script with this dependency into one single .jar file, so I can distribute it as such, and run the application from any filesystem path, as the script logic will be dependent on the path from which the execution was called.
I've tried with a few gradle fat jars examples out there but none have worked for me since the .jar file is constantly throwing Could not find or load main class Loading when I try it to run.
If anyone would be so kind to give a hint or to show an example of a gradle task that would do a build that fits my described needs I would be very gratefull.
I'm aware of the groovy module Grape with the #Grab annotation too, but I would leave that as a last resort since I don't want the users to wait for the dependencies download, and would like to bundle them with the app.
I'm using groovy 2.5.6 and gradle 4.10 for the project
Thanks
You can simply create the fat-jar yourself, without any extra plugin, using the jar Task. For a simple/small project like yours, it should be straightforward :
jar {
manifest {
// required attribute "Main-Class"
attributes "Main-Class": "com.mrhacki.myApp.Loading"
}
// collect (and unzip) dependencies into the fat jar
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
EDIT : pleas take other comments into consideration: if you have more that one external lib you might have issues with this solution, so you should go for a solution with "shadow" plugins in this case.
I want to build a jar file in IntelliJ IDEA with Gradle.
When I run my code in Intellij everything works fine,
but when I run the jar file I get an error:
SQLExecption: No suitable driver found for jdbc:sqlite:/applications/elite-dangerous/database/ED_Database.db
I build the jar throw pressing the build button.
It's strange for me because it works perfectly fine when I run it in IntelliJ IDEA.
Dependencies included using implementation config are not being included in the Jar which makes them not available in runtime. So, I guess that could be the case. You can try changing implementation to compile dependencies ( which is deprecated, so not recommended ) or You can include your dependencies in the jar as below
jar {
manifest {
attributes 'Main-Class': 'eliteDangerousRestUpdater.Main'
}
from {
compileJava.classpath.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
I'm using Spring REST Docs to generate documentation for our API.
I've added everything to build.gradle from tutorial here http://docs.spring.io/spring-restdocs/docs/current/reference/html5/
ext {
snippetsDir = file('build/generated-snippets')
}
test {
outputs.dir snippetsDir
}
asciidoctor {
attributes 'snippets': snippetsDir
inputs.dir snippetsDir
outputDir "build/asciidoc"
dependsOn test
sourceDir 'src/main/asciidoc'
}
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
After I do gradle build I can see that in build/asciidoc directory files are generated and also in build/generated-snippets.
But when I run from IDEA gradle task bootRun and trying to access localhost:8080/docs/index.html I'm getting not found 404. Just for test I've tried to put some index.html file under resources/static directory and then do bootRun and I can access localhost:8080/index.html file after that.
If I open my .jar file I can see static files under directory BOOT-INF/classes/static/docs so they are packed into jar.
Maybe somebody had the same issue?
There are two things that you need to do so that the documentation is served when using bootRun. The first is to copy the generated documentation into a location that's on the classpath used by bootRun:
task copyRestDocs(type: Copy) {
dependsOn asciidoctor
from "${asciidoctor.outputDir}/html5"
into "${sourceSets.main.output.resourcesDir}/static/docs"
}
Note that this new task depends on the asciidoctor task. This ensures that the documentation has been generated before it's copied.
Secondly, the bootRun task must depend on the new copyRestDocs task:
bootRun {
dependsOn copyRestDocs
}
I am trying to make my application work in a stand alone jar. The problem is, a jar is generated for my program, and a bunch of other jars are generated for the libraries. Is there any way to get these jars to get inside one? I am using Gradle if that helps.
The IntelliJ IDEA artifact config:
The output directory:
What I expected (and want) to happen:
You need a fat-jar (jar file with all it's dependencies inside). It's not a big problem for Gradle, you just need to make one additional task of type jar, which will collect all the dependencies and zip it alltogether
There are many examples, how you can do it, here is one of them. Take a closer look at task fatJar:
task fatJar(type: Jar) {
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}