Code for different Java versions with Gradle - java

Can I possibly make Gradle compile one part of my app for Java version 1.8 and the other for 1.7?
My situation is I'm writing a library, part of which will be used in a project where the version is 1.7.
I realize now that I could have broken logic in my thoughts, but the question still stands. Or, if possible, suggest something completely different.
EDIT: And if possible suggest any relevant terms, because I can't even think of a google query now.

Suppose you have a multi project build with the following directory structure:
root
build.gradle.kts
sub-project
build.gradle.kts
src/main/java
java-1.7-project
build.gradle.kts
-src/main/java
Root project build file:
plugins {
java
}
allprojects {
group = "com.company.example"
version = "0.0.1"
apply {
plugin("java")
}
repositories {
mavenCentral()
}
}
configure(subprojects.filter { it.name != "java-1.7" }) {
java.sourceCompatibility = org.gradle.api.JavaVersion.VERSION_11
}
Java-1.7-project build file:
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}

Related

Why am I getting "java.lang.NoClassDefFoundError" despite referencing the library in eclipse and specifying the dependency in build.gradle?

The error gets thrown for org/apache/commons/compress/archivers/tar/TarArchiveInputStream as seen here.
I have referenced this library in eclipse (as seen here)
The dependency has also been specified in build.gradle. The contents of the gradle file:
plugins {
id 'org.spongepowered.plugin' version '0.9.0'
}
group = pluginGroup
version = pluginVersion
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
dependencies {
compileOnly 'org.spongepowered:spongeapi:7.2.0'
annotationProcessor 'org.spongepowered:spongeapi:7.2.0'
compile 'org.apache.commons:commons-compress:1.21'
}
sponge.plugin.id = pluginId
Eclipse also does not flag any errors. Lines of code such as tarInput.getNextTarEntry() appear in the correct colour with no red underlining, and eclipse even autocompletes the names of methods found in commons-compress.
Given eclipse seems to be working correctly with the dependency, and given that running ./gradlew build leads to a successful build, I am therefore at a loss for why I am getting the java.lang.NoClassDefFoundError error.
#nitind helped. I focused upon runtime and found the problem was to do with my build.gradle file (even though the build was successful!). I changed it to this and the error has vanished:
buildscript {
repositories {
mavenCentral()
}
}
plugins {
id 'org.spongepowered.plugin' version '0.9.0'
}
apply plugin: 'java'
group = pluginGroup
version = pluginVersion
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
dependencies {
compileOnly 'org.spongepowered:spongeapi:7.2.0'
annotationProcessor 'org.spongepowered:spongeapi:7.2.0'
compile 'org.apache.commons:commons-compress:1.21'
}
jar {
from configurations.compile.collect { zipTree it }
}
sponge.plugin.id = pluginId

Struggling with Gradle Plugin for Configuring MultiProject Build

I've got my multi-project reusable build plugin built and published and my first project build is consuming it, but I don't understand why this doesn't work the way I think it should:
class TdkGradlePlugin implements Plugin<Project>
{
void apply(Project project)
{
project.subprojects
{
... // entire multiproject reusable build code for sub-projects here
}
}
}
There are a host of different complaints from gradle about this, but I'm thinking it's most likely that you just can't do this. If I can't do this, how do I encorporate all this logic in my plugin? It's several pages of gradle code defining how to build all my projects and it all worked 100% before I tried to move it into the plugin. This code looks roughly like this:
project.subprojects
{
apply plugin: 'java-library'
apply plugin: 'maven-publish'
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
dependencies
{
...
}
tasks.withType(Javadoc).all
{
enabled = false
}
clean.doFirst
{
...
}
apply plugin: 'eclipse'
eclipse
{
...
}
processResources
{
...
}
compileJava
{
...
}
etc ...
Thanks for any helpful hints!
Jon

How can I fix "Unresolved reference: java" in Spring Boot Kotlin project?

I have created Spring Boot project with
SDK 11. Java Version 11.0.3
Kotlin as language
Gradle
I'm following this Tutorial:
https://scotch.io/#grahamcox82/how-to-build-a-simple-rest-api-with-kotlin-and-spring-boot
I'm trying to
import java.time.Instant
in my Kotlin data class
And have an error
Unresolved reference: java
build.gradle.kts file:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.1.6.RELEASE"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
kotlin("jvm") version "1.2.71"
kotlin("plugin.spring") version "1.2.71"
}
group = "com.smight"
version = "0.0.1"
java.sourceCompatibility = JavaVersion.VERSION_1_8
val developmentOnly by configurations.creating
configurations {
runtimeClasspath {
extendsFrom(developmentOnly)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
Maybe I should install java library? How can I check this?
Can anyone help please?
According to some research, this error can appear in this conditions :
You created a Kotlin2Js project instead of Kotlin JVM (source), try to recreate your project by selecting the right project type
or
You are using a Kotlin version that does not support JDK 11 (source), install JDK 8 instead and reconfigure your JAVA_HOME environment variable
It may as well be an error in your build.gradle file, copy/paste it in your question if the solutions above doesn't work
To get a more specific error you should first clean the autogenerated files
$ ./gradlew clean
In a modularized Spring project using Kotlin DSL the unresolved reference error could occur because the submodules are bootable.
build.gradle.kts (Project)
...
subprojects {
...
tasks.getByName<BootJar>("bootJar") {
enabled = false
}
tasks.getByName<Jar>("jar") {
enabled = true
}
}
GL
The problem was that JDK was not correct found from IntelliJ
I solved the problem so:
File -> Project Structure -> SDKs -> "+"
Find the path to your SDK where it is installed
New Project
Copy/Paste
Rebuild

Configure Gradle for Kotlin with Java 1.7

Ok, so I'm new to Gradle and Kotlin and I am having a hard time understanding how things glue together here...
I need to configure a project that should run on Java 7 (client limitations -_-) and I want to use Kotlin with it.
Right now I have the following build.gradle file that is working but I want to ask a few things that I couldn't find anywhere else:
buildscript {
ext {
springBootVersion = '1.5.15.RELEASE'
kotlin_version = '1.1.1'
}
repositories {
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
group = 'com.springkotlin'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.7
targetCompatibility = 1.7
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-security')
compile('com.onelogin:java-saml:2.3.0')
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
runtime('org.springframework.boot:spring-boot-devtools')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
testCompile group: 'javax.inject', name: 'javax.inject', version: '1'
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.6"
}
}
Now the questions:
I have tried using kotlin_version = '1.2.70' (released last few days!) and I got the error KotlinPluginWrapper : Unsupported major.minor version 52.0. I'm guessing then this is due to Kotlin 1.2.X only being able to "compile" (is that the word?) with Java 8+. Is that right? Is 1.1.1 the right version to use here or is there a way to use 1.2.70 that would work with Java 7? Will I be missing a lot of stuff for using it?
I want to understand the 3 kotlin stuff I had to setup on the script. Correct me please:
kotlin-gradle-plugin: Is used to define which version of Kotlin I will be using(?)
apply plugin: 'kotlin': As far as I know from Gradle, this should add tasks to work with Kotlin but running gradle tasks I didn't see anything different... So what is it really for?
kotlin-stdlib-jdk7: I'm guessing this is Kotlin lib of functions, classes, etc. What I don't understand though is the difference between stdlib and stdlib-jdk7. The documentation says it contains "addition extension functions". But which ones? Also, should I define a version for this guy? Or does it automatically picks up the kotlin-gradle-plugin version?
Thanks in advance,
Currently the compiler of the Kotlin language requires JDK 8 to run. A project compiled with Kotlin can target any Java starting from Java 6.
A recipe to setup Gradle build of a project that runs on Java 7 is following:
run Gradle with Java 8 or later
for all Kotlin compile tasks
specify jvmTarget = "1.6" in kotlinOptions
specify path to JDK 7 in jdkHome in kotlinOptions
if your project contains java code specify sourceCompatibility, targetCompatibility convention properties of the Java plugin
specify the following options of all java compile tasks:
isFork = true
forkOptions.javaHome = "<path to JDK 7>"
for all Test tasks specify executable as "<path to JDK 7>/bin/java"
The full sample:
sourceCompatibility = 1.7
targetCompatibility = 1.7
def JDK_7 = System.getenv("JDK_7") // or some other way to get path to JDK 7 installation
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
jvmTarget = "1.6"
jdkHome = JDK_7
}
}
tasks.withType(JavaCompile) {
options.fork = true
options.forkOptions.javaHome = file(JDK_7)
}
test {
executable = "$JDK_7/bin/java"
}
Kotlin can target either Java 6 or Java 8 and I don't think this has changed. However, it is quite likely that the default has changed from Java 6 to Java 8, so try as suggested here:
compileKotlin {
sourceCompatibility = JavaVersion.VERSION_1_6
targetCompatibility = JavaVersion.VERSION_1_6
kotlinOptions {
jvmTarget = "1.6"
apiVersion = "1.2"
languageVersion = "1.2"
}
}
The version of kotlin-gradle-plugin is the version of the Kotlin compiler used to compile your code. The version of the stdlib is the version of your runtime library. It is highly recommended to use the same version here.
The apply plugin: kotlin adds some tasks under the hood - just continue using the java tasks like gradle assemble, gradle build and gradle run as they will invoke the kotlin specific tasks
kotlin-stdlib-jdk7 adds very little value - unless you use features of the java library that were introduced in java 7 and that have extensions from Kotlin's stdlib, you'll be fine to just use the default stdlib (which targets Java 6 and is a dependency of kotlin-stdlib-jdk7 anyways).

Using protobuf with Gradle (IntelliJ)

I am trying to generate code for a simple protobuf example using the build instructions given here. I have been trying for awhile but I am not able to see any auto generated code in my source root.
The following is my build.gradle file
buildscript {
ext {
springBootVersion = '2.0.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.google.protobuf'
group = 'io.ai.vivid'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencyManagement {
imports {
mavenBom 'com.amazonaws:aws-java-sdk-bom:1.11.228'
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.5.1-1"
}
generateProtoTasks.generatedFilesBaseDir = 'generated-sources'
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.14.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
dependencies {
compile 'io.grpc:grpc-netty-shaded:1.14.0'
compile 'io.grpc:grpc-protobuf:1.14.0'
compile 'io.grpc:grpc-stub:1.14.0'
}
Also in my build.gradle file IntelliJ complains that it cannot resolve name protobuf
Things I have tried
Sync gradle tool in IntelliJ. This is the most prominent solution
given in SO
Setting Build tools -> Gradle -> Runner -> Delelgate IDE build/run
actions on gradle to true
Clean rebuilding of the gradle project.
From my understanding of the GitHub post, when you use the protobuf plugin, the stub will be automatically generated for you. What am I missing?
You've applied idea plugin, but you didn't configure it. You need to tell idea plugin where to include the generated source code.
protobuf {
generatedFilesBaseDir = "$projectDir/src/generated"
}
idea {
module {
sourceDirs += file("${projectDir}/src/generated/main/java");
sourceDirs += file("${projectDir}/src/generated/main/grpc");
}
}
You can take a look
at a full example of a buildfile here: build.gradle
In case anyone else ends up here problems getting IntelliJ to recognise the generated sources (Red highlight imports , classes etc). Beware of the intellisense file size limit. If your generated protobuf code exceeds the default setitng of 2500KB then the file is ignored.
Got Help -> Edit custom properties and add an entry appropriate for your case e.g.
idea.max.intellisense.filesize=4000
Spent half a day faffing over different source set source folder, generated sources, and include / exclude directories. Turned out I just need to increase this value
Alternatively, you can use sourceSets:
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}

Categories

Resources