Gradle: includeFlat and sourceSets dependecy for per-platform builds - java

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.

Related

Use local jar as a dependency in my Gradle Java project

I have a local jar file named mylib.jar. I want to used it as a dependency in my Gradle Java project.
This is what I tried:
I created a libs/ folder under project root. I put the jar file under libs/ folder.
MyProject
->libs/mylib.jar
->build.gradle
->src/...
In my build.gradle:
apply plugin: 'java-library'
group 'com.my.app'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
flatDir {
dirs 'libs'
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
api files('libs/mylib.jar')
}
But I can't access the public classes defined in mylib.jar in my project code. Why?
===== More information =====
The content of my jar:
mylib.jar
> com.my.jar.package
>ClassFromJar.class
Here is how I use the jar:
// Compilation error: Cannot resolve symobl 'ClassFromJar'
import com.my.jar.package.ClassFromJar;
public class MyEntryPoint {
// Compilation error: Cannot resolve symbol 'ClassFromJar'
ClassFromJar instance = new ClassFromJar();
}
Similar answers suggesting
Local dir
Add next to your module gradle (Not the app gradle file):
repositories {
flatDir {
dirs 'libs'
}
}
Relative path:
dependencies {
implementation files('libs/mylib.jar')
}
Use compile fileTree:
compile fileTree(dir: 'libs', include: 'mylib.jar')
A flatDir repository is only required for *.aar(which is an Android specific library format, completely irrelevant to the given context). implementation and api affect the visibility, but these are also Android DSL specific). In a common Java module, it can be referenced alike this:
dependencies {
compile fileTree(include: ["*.jar"], dir: "libs")
}
And make sure to drop the *.jar into the correct one libs directory, inside the module.
I thinks you should use in dependency declaration compile name: 'mylib' in this case flatDir will search for mylib.jar.
You could try following build.gradle (it works in my project):
plugins {
id 'java'
}
apply plugin: 'java-library'
group 'dependency'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
flatDir {
dirs 'libs'
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile name: 'mylib'
}
Just in case:
1 - compiler must have access to lib directory and jar
example:
javac -cp .;lib\* *.java
2 - ALSO import must be mentioned in java file
example in your java add
import static org.lwjgl.glfw.GLFW.*;

Saving Gradle Dependencies to a Directory

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"
}

Gradle won't import a bintray dependency, but doesn't throw any error

I'm creating a project which uses the Squash SQL Library for Kotlin. I've added the dependency to my build.gradle file. When running the update it just finishes without outputting any errors. But the library is not getting imported in my project and doesn't appear at all.
The dependencies shown in IntelliJ:
My build.gradle file:
//Kotlin Stuff, nothing changed here
repositories {
mavenCentral()
maven {
url "http://dl.bintray.com/kotlin/squash"
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'org.jetbrains.squash:squash:0.2.2'
}
//Kotlin Stuff
The dependency you've added is just the parent-pom which doesn't have any jar's in the repo. Here is the list of the squash projects (http://dl.bintray.com/kotlin/squash/org/jetbrains/squash/):
squash-core
squash-graph
squash-h2
squash-jdbc
squash-postgres
squash-sqlite
I guess you want to import the squash-core so change
compile 'org.jetbrains.squash:squash:0.2.2'
to
compile 'org.jetbrains.squash:squash-core:0.2.2'

Build error with gradle Could not find method testCompile()

I'm new to gradle and I'm getting a build error that I don't really understand. My project is just an empty shell with the directory structure and no java source code. Here is my root build.gradle file
allprojects {
//Put instructions for all projects
task hello << { task -> println "I'm $task.project.name" }
}
subprojects {
//Put instructions for each sub project
apply plugin: "java"
repositories {
mavenCentral()
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.+'
}
when I execute the gradle build command the build fails because it doesn't know the testCompile method with this message:
Could not find method testCompile() for arguments [{group=junit, name=junit, version=4.+}] on root project
I use Gradle 2.5.
I've understood that this method is a part of the java plugin which I've loaded. I don't see what went wrong, can you help?
In case anyone comes here based on the Could not find method testCompile() error, by now the more probable cause is that you need to replace the deprecated testCompile by testImplementation.
See What's the difference between implementation and compile in Gradle?
The java plugin is only applied to subprojects, so the testCompile configuration, added by the java plugin, can only be used in subprojects. The below works:
allprojects {
//Put instructions for all projects
task hello << { task -> println "I'm $task.project.name" }
}
subprojects {
//Put instructions for each sub project
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.+'
}
}
It's saying that it can't find the method testCompile for the arguments check that you spelt it correctly making sure the name and group which you have as "junit" are all correct and also the version is correct another fix for this issue is adding the testCompile line in sub projects block.

Gradle: JDBC driver not compiled into JAR

I have a module build.gradle file that looks like this:
apply plugin: 'java'
sourceCompatibility = 1.5
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'mysql:mysql-connector-java:5.1.6'
}
I also have an artefact set up like this:
When I build this artifact, my classes are included but MySQL driver is not. When executed, MySQL driver class is not found. How do I build so that my JAR artifact (used as a library)
ccontains MySQL JDBC driver?
Configuring this in Gradle and IntelliJ is two different things. The most direct way to create a fat Jar in Gradle is:
jar {
from { configurations.runtime.collect { it.directory ? it : zipTree(it) } }
}
PS: Merging Jars can cause problems. In most cases it should not be done, in particular for a library.

Categories

Resources