Javadoc and --enable-preview - gradle

I am using Gradle 6.0.1 and JDK12 with preview features.
Having the following configuration to be able to compile, run and test:
tasks.withType(JavaCompile) {
options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
jvmArgs += '--enable-preview'
}
That works fine for all except javadoc generation that I defined as follows:
task generateJavadocs(type: Javadoc) {
source = sourceSets.main.allJava
options.jFlags("--enable-preview")
}
When running gradle generateJavadocs I receive compilation errors for the new switch expressions. Has anybody made it work with Javadoc?

I had faced the same problem with preview features of JDK 14 (and Gradle 6.3). This has worked for me:
javadoc.options {
addBooleanOption('-enable-preview', true)
addStringOption('-release', '14')
}
In your case, try:
task generateJavadocs(type: Javadoc) {
options {
addBooleanOption('-enable-preview', true)
addStringOption('-release', '12')
}
}

This answer enhances Manfred's answer and is for anybody who is trying to set the javadoc args using gradle's kotlin api. It took me awhile to figure out that access to addStringOption and addBooleanOption requires a cast.
tasks.withType<Javadoc> {
val javadocOptions = options as CoreJavadocOptions
javadocOptions.addStringOption("source", "14")
javadocOptions.addBooleanOption("-enable-preview", true)
}

Related

Gradle kotlin dsl with jfrog artifactory plugin - disable publish build info

I'm trying to stop our Artifactory job from publishing any build info. According to the JFrog docs, setting publishBuildInfo = false should do that for me. However, if I try to set the property in our gradle kotlin dsl, I get the following error:
Could not set unknown property 'publishBuildInfo' for task ':artifactoryPublish' of type org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask.
Here is our build.gradle.kts file. I replaced everything that should be irrelevant by ...:
...
plugins {
...
id("com.jfrog.artifactory") version "4.24.20"
...
}
...
artifactory {
setContextUrl("someUrl")
...
publish(delegateClosureOf<org.jfrog.gradle.plugin.artifactory.dsl.PublisherConfig> {
repository(delegateClosureOf<groovy.lang.GroovyObject> {
...
})
defaults(delegateClosureOf<groovy.lang.GroovyObject> {
invokeMethod("publications", "mavenJava")
setProperty("publishPom", true)
setProperty("publishArtifacts", true)
setProperty("publishBuildInfo", false)
})
})
}
Use invokeMethod
configure<org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention> {
publish {
defaults {
invokeMethod("setPublishBuildInfo", false)
}
}
}
I got this from the deleted answer. Not sure why it was deleted since it worked and saved my life :)
One more from me. Had been struggling with turning off that PublisherBuildInfo via Kotlin DSL in gradle. The above mentioned method didn't quite work for me so I ended up with
clientConfig.publisher.isPublishBuildInfo = false inside artifactory block
which worked for id("com.jfrog.artifactory") version "4.28.1".
For example:
...
artifactory {
setContextUrl("https://-our-artifactory-url")
clientConfig.publisher.isPublishBuildInfo = false
publish(
delegateClosureOf<PublisherConfig> {
repository(
delegateClosureOf<GroovyObject> {
...

Gradle disable javadoc except on deploy

I have enabled the javadoc for a project with
java {
withJavadocJar()
}
The problem with this is that the javadoc is built everytime the library is built. In my case, this takes several minutes. Is there a good way to make the javadoc only run on gradle deloy?
The following did the trick:
// Disables a task unless we're publishing something.
def disableUnlessPublishing(toDisable) {
toDisable.enabled = false
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks
.findAll { it.group == "publishing" }
.any { toDisable.enabled = true }
}
}
disableUnlessPublishing(tasks.javadocJar)
disableUnlessPublishing(tasks.javadoc)
disableUnlessPublishing(tasks.sourcesJar)

gradle maven publish Pom using kotlin-dsl

I have a multiplatform kotlin library project that publishes to maven and have been updating to the kotlin 1.3 multiplatform model and kotlin-dsl
The previous groovy gradle script has a modifyPom block, and i found an example here. However as soon as I add
val modifyPom : Closure<*> by ext
modifyPom(closureOf<MavenPom> {
// pom code in here
})
I get the same result no matter what is in the pom data, which is that the call of the modifyPom groovy closure breaks the build with a very vague error:
Build file '<path>\build.gradle.kts' line: 47
Open File
In other words the line number of the call of modifyPom groovy Closure, but nothing about the actual error.
I am using Gradle 5.0. Any help appreciated.
So - in Groovy I had this block for configuring POMs, and it worked just fine:
project.publishing.publications.forEach { publication ->
publication.pom.withXml {
def root = asNode()
root.appendNode("name", "libui")
root.appendNode("description", "Kotlin/Native interop to libui: a portable GUI library")
root.appendNode("url", POM_SCM_URL)
root.children().last() + {
licenses {
license {
name "MIT License"
url POM_SCM_URL
distribution "repo"
}
}
developers {
developer {
id "msink"
name "Mike Sinkovsky"
email "msink#permonline.ru"
}
}
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEV_CONNECTION
}
}
}
}
And how to convert it to Kotlin DSL?
Edit:
Well, was answered in https://github.com/JetBrains/kotlin-native/issues/2372
In Gradle Kotlin DSL it becomes:
project.publishing.publications.withType<MavenPublication>().forEach { publication ->
with(publication.pom) {
withXml {
val root = asNode()
root.appendNode("name", "libui")
root.appendNode("description", "Kotlin/Native interop to libui: a portable GUI library")
root.appendNode("url", POM_SCM_URL)
}
licenses {
license {
name.set("MIT License")
url.set(POM_SCM_URL)
distribution.set("repo")
}
}
developers {
developer {
id.set("msink")
name.set("Mike Sinkovsky")
email.set("msink#permonline.ru")
}
}
scm {
url.set(POM_SCM_URL)
connection.set(POM_SCM_CONNECTION)
developerConnection.set(POM_SCM_DEV_CONNECTION)
}
}
}
This problem was fixed by changing the definition of modifyPom to
val modifyPom : Closure<MavenPom> by ext
That fixed the original problem as posted, and the pom is now being modified. If anyone needs help, add a comment and hopefully I will notice

How do I get IntelliJ to recognize gradle generated sources dir?

So I have an XJC javaExec that spins like a top but IntelliJ doesn't recognize the generated output despite having marked generated-src/java as such. Do I need to tweak the idea plug-in or something?
Note: The plug-in itself is loaded in subProjects from the root build.gradle.
XJC Project:
description = "Generates sources and compiles them into a Jar for $project"
configurations { xjc }
dependencies {
xjc 'org.glassfish.jaxb:jaxb-xjc:2.2.11'
xjc 'org.glassfish.jaxb:jaxb-runtime:2.2.11'
}
task xjc (type:JavaExec) {
doFirst{
File generatedSrcDir = file("$buildDir/generated-src/java")
if (!generatedSrcDir.exists()) {
generatedSrcDir.mkdirs()
}
}
main = "com.sun.tools.xjc.XJCFacade"
classpath configurations.xjc
def argsList = [
"-mark-generated",
"-no-header",
"-verbose", // or -quiet or nothing for default.
"-target", "2.1",
"-encoding", "UTF-8",
"-d", "$buildDir/generated-src/java",
"-catalog","$projectDir/src/main/resources/commons-gradle.cat",
file("$projectDir/src/main/resources/v1/") ]
args argsList
inputs.files files(file("$projectDir/src/main/resources/v1/"))
outputs.files files(file("$buildDir/generated-src/java"),file("$buildDir/classes"))
}
compileJava {
dependsOn xjc
source "${buildDir}/generated-src"
}
In the project that depends on this one I simply have:
compile project(":path:to:schemas:the-test-schema")
I've tried:
idea {
module {
def buildDir = file("$buildDir")
def generatedDir = file("$buildDir/generated-src")
def listOfDirs = []
buildDir.eachDir { file ->
if (file.name != buildDir.name && file.name != generatedDir.name)
listOfDirs.add(file)
}
excludeDirs = listOfDirs.toArray()
generatedSourceDirs += file("$buildDir/generated-src/java")
scopes.COMPILE.plus += [ configurations.xjc ]
}
}
I'll point out a solution by Daniel Dekany, from a Gradle discussion thread actually linking to this question. To quote:
apply plugin: "idea"
...
sourceSets.main.java.srcDir new File(buildDir, 'generated/javacc')
idea {
module {
// Marks the already(!) added srcDir as "generated"
generatedSourceDirs += file('build/generated/javacc')
}
}
Works well for me.
The code of this answer, rewritten using Kotlin DSL, will look like this:
plugins {
idea
}
val generatedSourcesPath = file("out/production/classes/generated")
java.sourceSets["main"].java.srcDir(generatedSourcesPath)
idea {
module {
generatedSourceDirs.add(generatedSourcesPath)
}
}
In my case, it didn't work unless I added the generate sources directory to both sourceDirs and generatedSourceDirs:
def generatedSourcesDir = file('src/generated/main/java')
idea {
module {
sourceDirs += generatedSourcesDir
generatedSourceDirs += generatedSourcesDir
}
}
in 2020 you probably did not refresh the project in IDEA
because it actually works oob.
30 mins of reading outdated solutions :(
It's happening in some versions. There are some issues that we can look at and read carefully.
But for myself, from the IntelliJ IDEA 2019 the solutions below aren't working anymore:
https://youtrack.jetbrains.com/issue/IDEA-210065 (it says Obsolete)
https://youtrack.jetbrains.com/issue/IDEA-152581 (it's saying Fixed here)
https://youtrack.jetbrains.com/issue/IDEA-117540/generated-sources-inside-output-directory-are-excluded-by-default
https://intellij-support.jetbrains.com/hc/en-us/community/posts/4906059373074-Class-defined-in-generated-sources-not-found-by-Intellij-editor-but-found-by-compiler-gradle-build-
Discussion in the Gradle forum about this: https://discuss.gradle.org/t/how-do-i-get-intellij-to-recognize-gradle-generated-sources-dir/16847
According to #Daniel Dekany, this worked in IDEA 2017.1.2, and worked for me until 2019:
plugins {
id 'idea'
}
idea {
module {
generatedSourceDirs += file('build/generated/sources/annotationProcessor')
}
}
But from 2019 to 2022, the solution that worked for me was:
def generatedDir = "${buildDir}/generated/sources"
sourceSets {
main {
java {
srcDir generatedDir
}
}
}
idea {
module {
generatedSourceDirs.addAll(file(generatedDir))
}
}
ext {
// path to IDEA generated sources directory
ideaGeneratedSourcesDir = "$projectDir/src/main/generated"
}
compileJava {
//……
options.annotationProcessorGeneratedSourcesDirectory = file(ideaGeneratedSourcesDir)
//options.headerOutputDirectory.set(file(ideaGeneratedSourcesDir)) (tested no effect)
//……
}
// above work for me, and i try all method this question mentioned it's not work! env: idea2019.3, wrapped gradle6.3-all, zh-CN, JDK8, [x] annotation processing is disabled(no effect, in global settings ), no idea plugin([x]plugins {id idea}), [x]sourceSets no need to set(genereated srcDir)
myCodeGenExample:
task vertxCodeGen(type: JavaCompile) {
group 'build'
source = sourceSets.main.java
destinationDir = file(ideaGeneratedSourcesDir)
classpath = configurations.compileClasspath
options.annotationProcessorPath = configurations.annotationProcessor
options.debugOptions.debugLevel = "source,lines,vars"
options.compilerArgs = [
"-proc:only",
"-processor", "io.vertx.codegen.CodeGenProcessor",
// where the non Java classes / non resources are stored (mandatory) - the processors requires this option to know where to place them
"-Acodegen.output=$destinationDir.absolutePath",
]
}
refresh the gradle, continously exist

How to add gradle generated source folder to Eclipse project?

My gradle project generates some java code inside gen/main/java using annotation processor. When I import this project into Eclipse, Eclipse will not automatically add gen/main/java as source folder to buildpath. I can do it manually. But is there a way to automate this?
Thanks.
You can easily add the generated folder manually to the classpath by
eclipse {
classpath {
file.whenMerged { cp ->
cp.entries.add( new org.gradle.plugins.ide.eclipse.model.SourceFolder('gen/main/java', null) )
}
}
}
whereby null as a second constructor arg means that Eclipse should put the compiled "class" files within the default output folder. If you want to change this, just provide a String instead, e.g. 'bin-gen'.
I think it's a little bit cleaner just to add a second source directory to the main source set.
Add this to your build.gradle:
sourceSets {
main {
java {
srcDirs += ["src/gen/java"]
}
}
}
This results in the following line generated in your .classpath:
<classpathentry kind="src" path="src/gen/java"/>
I've tested this with Gradle 4.1, but I suspect it'd work with older versions as well.
Andreas' answer works if you generate Eclipse project from command line using gradle cleanEclipse eclipse. If you use STS Eclipse Gradle plugin, then you have to implement afterEclipseImport task. Below is my full working snippet:
project.ext {
genSrcDir = projectDir.absolutePath + '/gen/main/java'
}
compileJava {
options.compilerArgs += ['-s', project.genSrcDir]
}
compileJava.doFirst {
task createGenDir << {
ant.mkdir(dir: project.genSrcDir)
}
createGenDir.execute()
println 'createGenDir DONE'
}
eclipse.classpath.file.whenMerged {
classpath - >
def genSrc = new org.gradle.plugins.ide.eclipse.model.SourceFolder('gen/main/java', null)
classpath.entries.add(genSrc)
}
task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
doLast {
compileJava.execute()
def classpath = new XmlParser().parse(file(".classpath"))
new Node(classpath, "classpathentry", [kind: 'src', path: 'gen/main/java']);
def writer = new FileWriter(file(".classpath"))
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.setPreserveWhitespace(true)
printer.print(classpath)
}
}

Resources