Kotlin Quasar example not working - gradle

I am testing the Kotlin Quasar actor example.
Quasar and Kotlin – a Powerful Match
So the question is, is this example out of date and is there any documentation in which I can find out how to use Kotlin and Quasar?
This is my gradle.build file.
group 'no.inmeta.kotlin.akka'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.0.1'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "co.paralleluniverse:quasar-kotlin:0.7.4"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}

I'm part of the Quasar team.
The post cites Quasar tests which you can run by cloning the Quasar repo and running e.g. gradle :quasar-kotlin:build (requires Gradle installed) but for new projects/experiments I suggest to start instead from the Gradle template, kotlin branch which now uses the latest Kotlin 1.0.1-2 (and for simplicity the latest Quasar 0.7.5-SNAPSHOT that depends on it).
Starting from that template I built this project (more info about how to configure it and run it in the main README) that runs the same Quasar actor tests as normal programs rather than tests. Here's its build.gradle:
group 'no.inmeta.kotlin.akka'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlinVer = '1.0.1-2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVer"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
sourceCompatibility = 1.8 // 1.7
targetCompatibility = 1.8 // 1.7
configurations {
quasar
}
configurations.all {
resolutionStrategy {
failOnVersionConflict()
}
}
repositories {
// mavenLocal()
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/releases" }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
// maven { url 'https://maven.java.net/content/repositories/snapshots' }
}
ext.classifier = ':jdk8' // ':'
ext.quasarVer = '0.7.5-SNAPSHOT'
dependencies {
compile "co.paralleluniverse:quasar-core:${quasarVer}${classifier}"
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVer"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVer"
compile "co.paralleluniverse:quasar-kotlin:${quasarVer}"
quasar "co.paralleluniverse:quasar-core:${quasarVer}${classifier}#jar"
}
applicationDefaultJvmArgs = [
"-Dco.paralleluniverse.fibers.verifyInstrumentation=true",
"-Dco.paralleluniverse.fibers.detectRunawayFibers=false",
"-javaagent:${configurations.quasar.singleFile}" // =v, =d
]
// mainClassName = 'co.paralleluniverse.kotlin.actors1.PingPongKt'
mainClassName = 'co.paralleluniverse.kotlin.actors2.PingPongWithDeferKt'
task wrapper(type: Wrapper) {
gradleVersion = '2.12'
}
defaultTasks 'run'
Some notes about the differences with your build file:
Since I converted the tests to programs, I'm including the application plugin and its configuration (here, applicationDefaultJvmArgs and mainClassName) as well as setting the default Gradle task to run.
In addition to the above, a gradle wrapper has been generated and pushed so that ./gradlew is all you need on the command line, with no need to have a local Gradle installation (how to run it in an IDE depends on the IDE).
You need to run the Quasar agent (or AoT instrumentation but using the agent here) so there's a quasar configuration pointing to the artifact that is then used to pass the -javaagent:${configurations.quasar.singleFile} JVM argument.
Using Java 8 as Quasar has a specific optimized build for it.
Also note that there is now a 1.0 branch of the quasar-kotlin-jetbrains-webinar project (which is now the HEAD one in fact), which contains the companion source code of this guest webinar with IntelliJ, ported to the latest Kotlin and Quasar as well.
Let me know if this helps.

Related

How to setup a multi-module gradle project with Quarkus?

A multi-module gradle project with the Quarkus plugin applied in the root build.gradle.kts fails at the :quarkusBuild step with a NoSuchElementException:
> Task :quarkusBuild FAILED
building quarkus jar
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':quarkusBuild'.
> java.util.NoSuchElementException
The root build.gradle.kts is like so:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.72"
id("io.quarkus") version "1.9.1.Final"
}
group = "org.example"
version = "1.0-SNAPSHOT"
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply {
plugin("kotlin")
}
dependencies {
implementation(kotlin("stdlib"))
}
}
However move the line id("io.quarkus") version "1.9.1.Final" to the sub projects' build.gradle.kts and the build succeeds. It seems that the quarkus build step is run where the plugin is declared, rather than where it is actually applied.
Ideally I want to declare the plugin once in the root, then apply it to subprojects only, not have it execute against the root project, where there's obviously nothing to build.
Any ideas?
You need to add apply false
plugins {
kotlin("jvm") version "1.3.72" apply false
id("io.quarkus") version "1.9.1.Final" apply false
}
https://docs.gradle.org/current/userguide/plugins.html#sec:subprojects_plugins_dsl
Your build also assumes that every sub-module will be a Kotlin module which may or may not be true. You can do something a little more like this to apply specific configurations to specific tasks:
subprojects { subproject ->
subproject.tasks.withType(JavaCompile).configureEach {
sourceCompatibility = JavaVersion.VERSION_11
}
subproject.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
}
}
}

new gradle format confusion and migrating causes Could not find method testCompile()

I have a build.gradle with
plugins {
id {some plugin for all projects}
id "com.diffplug.spotless" version "5.1.1"
}
AND THEN I have an allprojects {} section that defines ONE apply plugin: 'jacoco' and a subprojects {} section that declares apply plugin: 'java' with a few others
Immediately adding spotless messed with stuff and errors out that it cannot find the java plugin so then I modify ALL plugins to be in the plugins section like so
plugins {
id "java"
id "checkstyle"
id "eclipse"
id "idea"
id "jacoco"
id "com.diffplug.spotless" version "5.1.1"
id "com.dorongold.task-tree" version "1.5" //This prints out a task tree (pretty print)
}
This then results in this error
Could not find method testCompile() for arguments [junit:junit:4.11] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
So for some reason the java plugin is lost. I can't figure out the right combination here to migrate everything to this new plugins section format.
How do I do that? I randomly tried putting a plugins section in allprojects and subprojects but that results in this new error
Could not find method plugins() for arguments [build_d8c2jgy4ua1m0vkv9kmvgefmc$_run_closure2$_closure5#62337fda] on root project 'providersvc-all' of type org.gradle.api.Project
How does this new plugins section work? I can't seem to migrate without it breaking everything. I just want java plugin, testCompile, and spotless to play nicely together right now
EDIT(forgot to attach the full trimmed down file that does not work):
plugins {
id "java"
id "com.diffplug.spotless" version "5.1.1"
}
ext {
//dependency versions every project usees so we version in one location all jars(less jar hell this way)
deps = [
'junit': 'junit:junit:4.11'
]
}
allprojects {
repositories {
jcenter()
mavenCentral()
maven {
//webpieces VERSIONED snapshots so you can lock on a snapshot
url "https://dl.bintray.com/deanhiller/maven"
}
//For testing locally
maven {
url uri('/tmp/myRepo/')
}
}
}
subprojects {
dependencies {
testCompile deps['junit']
}
}
thanks,
Dean
You are only applying the plugins to the root project - not the sub-projects. However, if you like to configure plugins through the subprojects configuration, you have to use the apply plugin syntax. But you don't have to use the old buildscript block for configuring the classpath and repositories if you a combination of the two.
Here is an example. I am assuming the root project is not a Java project. I have also removed your comments and inserted mine instead for the sole reason to make them easier to spot.
plugins {
id "com.diffplug.spotless" version "5.1.1" apply false // <-- Set "apply false" here
// This makes it configure which version to use on the classpath for the entire build, but without applying it.
// Notice that the Java plugin is not specified here anymore.
// This is because it is a core plugin so you can't set the version (and I am assuming you don't want it on in the root project).
}
ext {
deps = [
'junit': 'junit:junit:4.11'
]
}
allprojects {
repositories {
jcenter()
mavenCentral() // <-- You can remove this if you want as it is already present as a proxy in jcenter().
maven {
url "https://dl.bintray.com/deanhiller/maven"
}
maven {
url uri('/tmp/myRepo/')
}
}
}
subprojects {
// Here are the two plugins
apply plugin: "java"
apply plugin: "com.diffplug.spotless"
dependencies {
testImplementation deps['junit'] // <-- testCompile renamed to testImplementation as the former has been deprecated for a long time
}
}

How do I use the native JUnit 5 support in Gradle with the Kotlin DSL?

I want to use the built-in JUnit 5 with the Gradle Kotlin DSL, because during build I get this warning:
WARNING: The junit-platform-gradle-plugin is deprecated and will be discontinued in JUnit Platform 1.3.
Please use Gradle's native support for running tests on the JUnit Platform (requires Gradle 4.6 or higher):
https://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle
That links tells me to put
test {
useJUnitPlatform()
}
in my build.gradle, but what is the syntax for build.gradle.kts?
My current build file is
import org.gradle.api.plugins.ExtensionAware
import org.junit.platform.gradle.plugin.FiltersExtension
import org.junit.platform.gradle.plugin.EnginesExtension
import org.junit.platform.gradle.plugin.JUnitPlatformExtension
group = "com.example"
version = "0.0"
// JUnit 5
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.junit.platform:junit-platform-gradle-plugin:1.2.0")
}
}
apply {
plugin("org.junit.platform.gradle.plugin")
}
// Kotlin configuration.
plugins {
val kotlinVersion = "1.2.41"
application
kotlin("jvm") version kotlinVersion
java // Required by at least JUnit.
// Plugin which checks for dependency updates with help/dependencyUpdates task.
id("com.github.ben-manes.versions") version "0.17.0"
// Plugin which can update Gradle dependencies, use help/useLatestVersions
id("se.patrikerdes.use-latest-versions") version "0.2.1"
}
application {
mainClassName = "com.example.HelloWorld"
}
dependencies {
compile(kotlin("stdlib"))
// To "prevent strange errors".
compile(kotlin("reflect"))
// Kotlin reflection.
compile(kotlin("test"))
compile(kotlin("test-junit"))
// JUnit 5
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
testRuntime("org.junit.platform:junit-platform-console:1.2.0")
// Kotlintest
testCompile("io.kotlintest:kotlintest-core:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-assertions:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-runner-junit5:3.1.0-RC2")
}
repositories {
mavenCentral()
mavenLocal()
jcenter()
}
(The following is some blabla because this question 'contains mostly code').
I tried to find documentation on how to customize tasks in the Kotlin DSL, but I couldn't find any. In normal Groovy you can just write the name of the task and then change things in the block, but the Kotlin DSL doesn't recognise the task as such, unresolved reference.
Also, this question is related but asks for creating of new tasks, instead of customize existing tasks: How do I overwrite a task in gradle kotlin-dsl
Here is a solution for normal Gradle.
[Edit april 2019] As Pedro has found, three months after I asked this question Gradle actually created a user guide for the Kotlin DSL which can be visited at https://docs.gradle.org/current/userguide/kotlin_dsl.html
They also added a migration guide from Groovy to Kotlin at https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/
Answer:
The syntax you ask for is
tasks.test {
// Use the built-in JUnit support of Gradle.
useJUnitPlatform()
}
which I figured out from this example file from the Kotlin DSL GitHub, or you can use
tasks.withType<Test> {
useJUnitPlatform()
}
which is used in the this official userguide which was created a couple of months after this answer was written (thanks to Pedro's answer for noting this).
But in any case you actually are still using the buildscript block, which is a bit deprecated itself, use the new plugins DSL instead (docs). New build.gradle.kts becomes
group = "com.example"
version = "0.0"
plugins {
val kotlinVersion = "1.2.41"
application
kotlin("jvm") version kotlinVersion
java // Required by at least JUnit.
// Plugin which checks for dependency updates with help/dependencyUpdates task.
id("com.github.ben-manes.versions") version "0.17.0"
// Plugin which can update Gradle dependencies, use help/useLatestVersions
id("se.patrikerdes.use-latest-versions") version "0.2.1"
}
application {
mainClassName = "com.example.HelloWorld"
}
dependencies {
compile(kotlin("stdlib"))
// To "prevent strange errors".
compile(kotlin("reflect"))
// Kotlin reflection.
compile(kotlin("test"))
compile(kotlin("test-junit"))
// JUnit 5
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
testRuntime("org.junit.platform:junit-platform-console:1.2.0")
// Kotlintest
testCompile("io.kotlintest:kotlintest-core:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-assertions:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-runner-junit5:3.1.0-RC2")
}
repositories {
mavenCentral()
mavenLocal()
jcenter()
}
tasks {
// Use the native JUnit support of Gradle.
"test"(Test::class) {
useJUnitPlatform()
}
}
(Since the Gradle Kotlin DSL has almost no documentation at all except a few (undocumented) example files on GitHub, I'm documenting a few common examples here.)
(Complete example project at GitHub, self-promotion...)
Adding on top of accepted answer, it is also possible to use typed task configuration like:
tasks.withType<Test> {
useJUnitPlatform()
}
Update:
Gradle docs for reference here. Specifically Example 19 which has:
tasks.withType<JavaCompile> {
options.isWarnings = true
// ...
}
this worked for me till now...
plugins {
kotlin("jvm") version "1.7.10"
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter:5.9.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}

SpringBoot with Gradle missing dependency for Thymeleaf

I'm trying to setup a very simple Springboot application using Thymeleaf as my templating engine. I am %100 certain my #Controller is working fine but when I try to access the default url ("/") I get the dreaded "Whitelabel" error page.
Below is my gradle.build file...
buildscript {
ext { springBootVersion = '1.4.0.RELEASE' }
repositories { mavenCentral() }
dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
jar {
baseName = 'masterSpringMvc'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories { mavenCentral() }
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
Pretty sure I got everything setup right, so I go ahead and run the below build steps...
After this I am expecting to see the spring-boot-starter-thymeleaf.jar in my "Project and External Dependencies" but its not there. I'm very new to Gradle and was assuming that the build would pull in this required dependency, and then it would be "enabled" while starting my application. Any clue what I might be doing wrong here?
Here is my .html page, I am expecting to see "Test" displayed in the browser.
You need to update dependencies.
On Package Explorer:
-> right click your project -> Gradle ->Enable Dependency Management -> right click it again -> Refresh Dependencies

Building a fully executable Spring Boot 1.3 war from a Gradle multi project build

I'm trying to build a fully executable WAR using Spring Boot 1.3 as per https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html. If I build a single Gradle project, it all works fine, but I havea multi project build, where I have a "root" project and then several projects underneath it, and I cannot get it to build anything but a standard, "fat" WAR file, without the providedRuntime of Jetty and without the scripts to make it run.
Does anyone know how to do this?
In my root project, I have the following (abridged):
buildscript {
repositories {
mavenCentral()
}
ext {
springBootVersion = '1.3.0.RELEASE'
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
}
allprojects {
//Put instructions for all projects
repositories {
mavenCentral() // jcenter is missing spring-orm.4.1.6.RELEASE jar file so try mavenCentral first
jcenter {
url "http://jcenter.bintray.com/"
}
maven { url 'http://repo.opensourceagility.com/release' }
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'spring-boot'
}
and then in the subproject which is a web project, and which I'm trying to build, I have:
apply plugin: 'war'
dependencies {
// Include related projects
compile project(':project-model')
compile project(':project-dynamoDB')
// Core Spring Boot - note version is set in main build.gradle file
compile 'org.springframework.boot:spring-boot-starter-web'
// Remove Tomcat (included in -web) and include Jetty instead
providedRuntime 'org.springframework.boot:spring-boot-starter-jetty'
// Other Spring modules
compile 'org.springframework.boot:spring-boot-starter-social-facebook'
compile 'org.springframework.boot:spring-boot-starter-social-linkedin'
compile 'org.springframework.social:spring-social-google:1.0.0.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
compile 'org.springframework.boot:spring-boot-starter-security'
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.boot:spring-boot-devtools'
compile 'org.springframework:spring-context'
compile 'org.springframework:spring-context-support'
}
configurations {
providedRuntime.exclude group: 'org.springframework.boot', module:'spring-boot-starter-tomcat'
all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' // exclude when using log4j
}
springBoot {
mainClass = 'rs.web.Weblication'
executable = true
}
bootRun {
addResources = true
}
processResources {
// exclude resources if they look like they're profile dependent but don't match the current env/profile
eachFile { d ->
if(d.name.endsWith('.xml') || d.name.endsWith('.yaml') || d.name.endsWith('.properties')) {
//def fname = d.name.replaceFirst(~/\.[^\.]+$/, '')
//if(fname.indexOf("-") > -1 && ! fname.endsWith("-" + environment)) {
// d.exclude()
//} else {
// replace #variables# listed below in properties/config files
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [
activeProfiles: environment
])
//}
}
}
}
war {
baseName = 'project-web'
version = '1.0.0'
manifest {
attributes 'Implementation-Title': baseName,
'Implementation-Version': version
}
webXml = file('src/main/resources/web.xml')
// rename the war task which has profiles appended from warName-profile,profile2.war
// to warName-profile.profile2.war
classifier = environment.replaceAll(',','-')
}
but when I build it (./gradlew build, or ./gradlew subprojectname:build), all is well and a working WAR is created, but not an executable one.
With a single project, I have it working fine.
Ah ha, right well I build a test multi-project build and it worked OK, so it was clearly the configuration above.
I worked through a process of elimination and it turns out that the problematic area was the line
classifier = environment.replaceAll(',','-')
which is intended to rename files with environment variables as part of the name. This process seems to get in the way of the script addition; perhaps it could be applied afterwards if it's really necessary.

Resources