Saving Gradle Dependencies to a Directory - java

How can I save all the dependent jars for a module to a directory? I have an application that runs in IntelliJ IDEA, but I want to run it on another computer so I need to copy all the JAR files there.

Firstly, please consider using Gradle (or Gradle Wrapper) to do such things like getting/downloading dependencies of a project on another computer. But if you need to copy dependencies for any other reason you can define a task similar to:
task copyDependencies(type: Copy) {
from configurations.runtime
into "lib"
}
When you run:
gradle copyDependencies
runtime dependencies will be copied to a lib/ folder.
Example
build.gradle
apply plugin: 'groovy'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.1'
compile group: 'com.h2database', name: 'h2', version: '1.4.196'
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4'
}
task copyDependencies(type: Copy) {
from configurations.runtime
into "lib"
}
Command:
gradle copyDependencies
And lib/ directory contains:
lib
├── groovy-all-2.3.11.jar
├── h2-1.4.196.jar
└── jackson-core-2.9.1.jar
Use Gradle Wrapper
As I mentioned earlier, please consider using Gradle Wrapper so you don't have to worry about if there is a Gradle distribution installed on another computer. As stated in the documentation you can easily add Gradle Wrapper and then you can run
./gradlew [task]
by using wrapper instead of Gradle installed on your OS. In your case running
./gradlew build
will download all dependencies and build the project. It's way better than copying dependencies manually, Gradle was invented to do it for us.

following solution worked for me
configurations.implementation.setCanBeResolved(true)
configurations.api.setCanBeResolved(true)
task copyDependencies(type: Copy) {
from configurations.implementation
into "libs"
}

Related

Generated resource output not found in test classpath in gradle build

I am attempting to configure a gradle (version 4.6) build (as a part of a multi-module project) that uses a Java "script" to generate resources into the main sourceSet, which are then referenced in my test configuration. The idea is that I'd ultimately like to create a jar that is simply a resource bundle for inclusion in another module of my build, but I have java files both to generate these resources and to execute verification tests on them before packaging.
I currently have three sourceSets configured: the standard "main" and "test", and a custom sourceSet "generator" which holds resources used as inputs to the generator "script" and the source for the generator script itself. I've registered a main output directory according to this documentation (see "working with generated resources"), pointing to a JavaExec class that runs the generator with the "generator" sourceSet runtime classpath to output resources into the main classpath.
All of this appears to work- I can find the output in the correct directory when running :<module>:build, showing that the script is both running properly and that it is done as a dependency to the main compile task. However, when I try to reference the generated output in the tests with getClass().getClassLoader().getResource("<baseGeneratedOutputDirectory>"), I get a null value back, suggesting that my generated output is not being included in the test runtime classpath. The documentation clearly states that the...
Java plugin will use those dirs in calculating class paths and for jarring the content
...so I'm not sure why my files aren't getting picked up. Below is my abridged build.gradle file. Note that I'm overriding the generator task type in order to set it up with build caching, but I still see this bug with caching turned off.
apply plugin: 'java-library'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
sourceSets {
generator {
java.srcDirs = ['src/generator/java']
resources.srcDirs = ['src/generator/resources']
}
main {
java
resources
output.dir("$buildDir/generated-files/main", builtBy: 'generateConfig')
}
test {
java
resources
}
}
dependencies {
api project(':server:server_protobuf_classes');
api project(':common:game-config-util')
api 'com.google.protobuf:protobuf-java:3.5.1'
generatorImplementation project(':common:game-config-util')
generatorImplementation project(':server:server_protobuf_classes');
generatorImplementation group: 'commons-io', name: 'commons-io', version: '2.5'
// ...
testCompile group: 'junit', name: 'junit', version: '4.11'
testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'
testCompile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
// ...
}
task generateConfig(type: GenerateConfig) {
outputs.dir("$buildDir/generated-files/main")
classpath sourceSets.generator.runtimeClasspath
main = "com.project.ProtobufConfigurationProcessor"
}
#CacheableTask
class GenerateConfig extends JavaExec {
}
EDIT: Adding the following makes the tests pass, but I'm confused why I'd need to manually configure the test resource directory like this. Shouldn't the test task pick up build output from the main source set by default?
sourceSets {
test {
resources.srcDirs = ["$buildDir/generated-files/main"]
}
}

Why does this dependency not show up as one added by Gradle even when it was?

Following the suggestion on this thread, I added the jars I wanted to reference in a folder named lib in the project root and I added the following gradle dependencies to my project:
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-config')
compile('org.springframework.cloud:spring-cloud-starter-eureka')
compile('org.springframework.boot:spring-boot-starter-web')
compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2'
compile files('/lib/aspose-cells-17.02.0.jar');
compile files('/lib/bcprov-jdk16-146.jar');
}
Now, when I look at File -> Project Structure -> Modules -> Dependencies (tab) in IntelliJ, it shows every other dependency as having been added by Gradle except the two files I included above.
Is that the way it is supposed to appear? Have I done anything wrong? Or is there another way to make the word Gradle: appear in front of those dependencies?

Multiproject build: dependency to tests jar

I'm restructuring/refactoring build process for a big(ish) project. Currently it contains over a dozen separate modules built with standalone build scripts each. I want to integrate them all into a single multiproject build in Gradle.
After I integrated all sources into a single tree, fixed build.gradles, I came upon the following problem. Dependencies for many modules contain something like:
dependencies {
compile group: 'com.company', name: 'Module', version: '1.2.3'
// ...
testCompile group: 'com.company', name: 'Module', version: '1.2.3', classifier: 'tests'
}
I want the build to use jars from the subproject, not from a repository. I replaced compile ... with compile project(':Module') and it works fine. However, I cannot find the way to pass 'tests' specifier to the testCompile project... dependency.
Is there a way to pick up the tests jar as a dependency to testCompile?
In the producing project you will need to declare the "Test" JAR as outgoing artifact.
configurations {
testUtils
}
task testUtilsJar(type: Jar) {
...
}
artifacts {
testUtils testUtilsJar
}
In the consuming project you depend on it as such:
dependencies {
testCompile project(path: ':Module', configuration: 'testUtils')
}

How to add a local jar dependency to another dependency in gradle?

The jar amazon-kinesis-connectors is using amazon-kinesis-client. I want to change this dependency to a local custom jar:
dependencies {
compile ('com.amazonaws:amazon-kinesis-connectors:1.2.0'){
exclude group: "com.amazonaws", module: "amazon-kinesis-client"
}
compile files('libs/amazon-kinesis-client-1.6.3.jar')
//...
}
It compiles ok, but when I'm running the code I get java.lang.NoClassDefFoundError: com/amazonaws/services/kinesis/clientlibrary/interfaces/IRecordProcessorFactory. Is there a way to do this dependency management in gradle?
As environment I'm using:
gradle 2.13
intellij idea CE 2006.1
java 1.8
Edit:
dependency graph in intellij:
Running using a gradle task:
task run_app(type:JavaExec) {
main = 'org.main.RunApp'
classpath = sourceSets.main.runtimeClasspath
}
try below gradle configuration
dependencies {
compile ('com.amazonaws:amazon-kinesis-connectors:1.2.0'){
exclude group: "com.amazonaws", module: "amazon-kinesis-client"
}
compile files('libs/amazon-kinesis-client-1.6.3.jar')
runtime files('libs/amazon-kinesis-client-1.6.3.jar')
//...
}
or you can use application plugin to create executable jar
https://docs.gradle.org/current/userguide/userguide_single.html#application_plugin

Gradle: includeFlat and sourceSets dependecy for per-platform builds

I'm new to Java world and Gradle. I've made a JSerial lib which will support multiple platforms (Android, Linux and Windows).
To be able to choose the platform I'm targetting, I've defined some sourceSets in my JSerial gradle file:
sourceSets {
windows {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
linux {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
dependencies {
linuxCompile 'net.java.dev.jna:jna:4.1.0'
linuxCompile 'net.java.dev.jna:jna-platform:4.1.0'
windowsCompile 'net.java.dev.jna:jna:4.1.0'
windowsCompile 'net.java.dev.jna:jna-platform:4.1.0'
}
The default main sourceSets builds the common interface, etc. Then the windows sourceSet will build windows implementation (and same for Linux and Android).
I create a project which uses this library and depends on it using gradle's includeFlat. Here is the dependency part of my gradle file:
dependencies {
compile project(':JSerial')
testCompile group: 'junit', name: 'junit', version: '4.11'
}
This works. But I would like to depends on the "windows" sourceSet, because this project is a windows application. I tried the following:
dependencies {
compile project(':JSerial').sourceSets.windows.output
testCompile group: 'junit', name: 'junit', version: '4.11'
}
But it doesn't work, I have the following error:
Could not find property 'windows' on SourceSet container.
What's wrong ?
PS: If there is a better way to do what I'm trying without using sourceSets, please tell me !
I finally found a solution which I think is elegant. Instead of using sourceSets I used multi-project. Here is my project:
Serial/
build.gradle
src/main/java/com.package/
SerialPort.java
windows/
build.gradle
src/main/java/com.package/
SerialPortWindows.java
Application/
build.gradle
settings.gradle
In my Application's settings.gradle:
includeFlat 'Serial'
includeFlat 'Serial/windows'
In my Application's build.gradle:
dependencies {
project(':Serial/windows')
}
In my Serial/windows's build.gradle (which requires SerialPort interface to compile):
dependencies {
project(':Serial')
}
Then when I build my application, it requires Serial/windows which requires Serial. I think I will be able to defines multiple build.gradle files for my application (for example one for Linux and one for Windows), whith different dependencies.

Categories

Resources