WIP: AVRO-4223 Gradle plugin for generating Java code#3614
WIP: AVRO-4223 Gradle plugin for generating Java code#3614frevib wants to merge 99 commits intoapache:mainfrom
Conversation
Fix Intellij not finding generated sources Add generating BigDecimal property
Add dynamic output directory
|
@raphaelauv did you test the latest release https://plugins.gradle.org/plugin/eu.eventloopsoftware.avro-gradle-plugin? No need to add |
|
I have created https://issues.apache.org/jira/browse/INFRA-27616 for the requirement from Gradle to prove the ownership of avro.apache.org DNS domain. |
| private fun instantiateAdditionalVelocityTools(velocityToolsClassesNames: List<String>): List<Any> { | ||
| return velocityToolsClassesNames.map { velocityToolClassName -> | ||
| try { | ||
| Class.forName(velocityToolClassName).getDeclaredConstructor().newInstance() |
There was a problem hiding this comment.
Why this uses the current class' loader ?
loadLogicalTypesFactories() and doCompile() use the thread's class loader
There was a problem hiding this comment.
I've used the same as in the Maven plugin:
and:
| compileSchemaTask.protocolFiles.from( | ||
| project.fileTree(sourceDirectory).apply { | ||
| setIncludes(includesProtocol) | ||
| setExcludes(extension.excludes.get()) |
There was a problem hiding this comment.
We're not making a distinction between main and test includes/excludes like in the Maven plugin. If you compile for the test classpath, the same value is used from includedSchemaFiles, excludedSchemaFiles, includedProtocolFiles and excludedProtocolFiles.
It's a bit of design choice, but I thought it's a bit unnecessary to have this distinction. Thoughts?
| </execution> | ||
| <execution> | ||
| <id>run-gradle-task-publish</id> | ||
| <phase>deploy</phase> |
There was a problem hiding this comment.
We use deploy to deploy -SNAPSHOTs for the Maven artefacts.
AFAIK Gradle plugins repo does not allow -SNAPSHOTs
There was a problem hiding this comment.
Correct, the Gradle plugin portal does not support snapshots. It works different than Sonatype, where you first push and later release via the Sonatype UI. With the Gradle publish plugin when you run ./gradlew publishPlugins you'll immediately publish the plugin to the portal.
You can however publish -SNAPSHOT to the local Maven repo with ./gradlew publishToMavenLocal
|
Hello! I haven't been following this, and I'm catching up, but I'm really grateful for the work you've already put into this! I am wholeheartedly for getting the gradle plugin moving for the next Avro release. As a donation, are you willing to move the package into the Does anybody have concerns about integrating kotlin code into the Avro repo? I'm not against it but I'm not as familiar with Kotlin. |
| for (sourceFile in schemaFileTree.files) { | ||
| parser.parse(sourceFile) | ||
| } |
There was a problem hiding this comment.
This loop assumes that a single pass of all files is sufficient to parse all input files, however in the case of an unresolved schema exception multiple passes may be required.
The old plugin solves this inside its SchemaResolver by delaying the parsing of these unresolved schemas (see call on line 67) and then requeueing them after each successfully parsed schema (see the call on line 55).
This can easily happen for instance in the default value validation step for record fields when using an enum that has not been parsed yet due to how the filetree walk has ordered the schema files.
There was a problem hiding this comment.
As a POC i've tried using a custom task definition extending from the AbstractCompileTask that changes the loop a bit to allow multiple passes until nothing successfully parses anymore. This works for the mentioned issue but i am not sure whether the protocol parsing also needs logic like this.
val remainingWork: MutableList<File> = schemaFileTree.files.toMutableList()
val delayedWork: MutableList<File> = mutableListOf()
val suppressedExceptions: MutableList<Exception> = mutableListOf()
while (remainingWork.isNotEmpty()) {
val nextWork = remainingWork.removeFirst()
try {
parser.parse(nextWork)
if (delayedWork.isNotEmpty()) {
delayedWork.forEach { remainingWork.addLast(it) }
delayedWork.clear()
}
} catch (e: RuntimeException) {
if (e.message?.contains("unresolved schema") == true) {
delayedWork.add(nextWork)
suppressedExceptions.add(e)
} else {
throw e
}
}
}
if (delayedWork.isNotEmpty()) {
val e = GradleException("Unable to parse some schema files, see suppressed exceptions.")
suppressedExceptions.forEach { e.addSuppressed(it) }
throw e
}
What is the purpose of the change
Gradle plugin to generate Java code from Avro files
Verifying this change
This change added tests and can be verified as follows:
cd to
avro/lang/java/gradle-plugin./gradlew testDocumentation
Release
https://plugins.gradle.org/plugin/eu.eventloopsoftware.avro-gradle-plugin
0.0.2is released and fully works with AVSC files:0.0.50.0.80.1.0this release adds Protocol support.0.1.1Fix issue with Gradle multi project, where sources would not appear on the classpathInstallation instructions: https://github.com/frevib/avro/blob/AVRO-4223-gradle-plugin/lang/java/gradle-plugin/README.md#version
An official release will be done in the coming month