How gradle plugin using DSL works?

Viewed 413

I am getting confused, please someone correct me

From Gradle plugin portal it says use below approach to add a plugin

-------Using the plugins DSL:--------------------
plugins {
    id "com.github.edeandrea.xjc-generation" version "1.4"
}

-------Using legacy plugin application:--------
buildscript {
   repositories {
      maven {
        url "https://plugins.gradle.org/m2/"
      }
   }
   dependencies {
      classpath "gradle.plugin.com.github.edeandrea:xjc-generation-gradle-plugin:1.4"
   }
}

apply plugin: "com.github.edeandrea.xjc-generation"

The legacy approach is pretty much clear: as per my understanding it will find that dependency in repositories (specified maven URL) and add it to the classpath so that the application can pick the specified plugin

But in case of new approach (i.e. using DSL) it doesn't say anything, what I understand is the plugin must be published in official Gradle repo in order to access it, but how the build.gradle files know where to find it, meaning do we need to add repositories {} block and specify mavencentral() in it to make it work or need to add anything else ?

Also pluginMangement block present in settings.gradle controls the new plugin approach, I have tried defining the repositories {} block and added mavencentral() but it doesn't work.

In short, how plugin added using DSL works, which block tells from where to find that plugin and then which line tells to add it in the classpath.

Updates: For ex, the maven block in repositories-buildscript section tells to look the plugin under url "https://plugins.gradle.org/m2/ location and classpath tag in dependencies-buildscript tells to add this dependency into application classpath

Correction: mavenCentral()

2 Answers

The plugins DSL can be thought of as the declarative way of applying plugins and the legacy plugin application can be thought of as imperative.

But in case of new approach (i.e. using DSL) it doesn't say anything, what I understand is the plugin must be published in official Gradle repo in order to access it, but how the build.gradle files know where to find it, meaning do we need to add repositories {} block and specify mavencentral() in it to make it work or need to add anything else ?

This is thoroughly explained in the documentation: Plugin Marker Artifacts .

Also pluginMangement block present in settings.gradle controls the new plugin approach, I have tried defining the repositories {} block and added mavencentral() but it doesn't work.

It is mavenCentral(), not mavencentral()

pluginManagement {
    repositories {
        mavenCentral()
    }
}

rootProject.name = "example"

In short, how plugin added using DSL works, which block tells from where to find that plugin and then which line tells to add it in classpath.

This is all explained in the documentation: Applying plugins with the plugins DSL

So I was facing the same issue in my gradle+Java 11 project and I solved using https://github.com/edeandrea/xjc-generation-gradle-plugin. It is not as simple as it seems to be. Usually, it is necessary to add other dependencies, which was my case. my build.gradlw looks like:

plugins {
    id 'java'
    id "com.github.davidmc24.gradle.plugin.avro" version "1.0.0"
    id 'idea' // optional (to generate IntelliJ IDEA project files)
    id 'com.github.edeandrea.xjc-generation' version '1.6'
}

description = "spring-kafka-stream"
group = 'com.github.felipegutierrez.explore.spring'
version = '0.0.1'
sourceCompatibility = '11'

ext {
    jaxbVersion = '2.3.1'
}

dependencies {
    ...
    implementation "javax.xml.bind:jaxb-api:$jaxbVersion"
    xjc "javax.xml.bind:jaxb-api:$jaxbVersion"
    xjc "org.glassfish.jaxb:jaxb-runtime:$jaxbVersion"
    xjc "org.glassfish.jaxb:jaxb-xjc:$jaxbVersion"
}

xjcGeneration {
    defaultAdditionalXjcOptions = ['encoding': 'UTF-8']
    schemas {
        order {
            schemaFile = 'order.xsd'
            javaPackageName = 'com.github.felipegutierrez.explore.spring.model'
        }
    }
}

Besides all the xjc dependencies I had to add implementation "javax.xml.bind:jaxb-api:$jaxbVersion". Then I create the file src/main/schemas/xjc/order.xsd:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="order">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="order-by" type="xs:string"/>
                <xs:element name="ship-to">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name" type="xs:string"/>
                            <xs:element name="address" type="xs:string"/>
                            <xs:element name="city" type="xs:string"/>
                            <xs:element name="country" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="item" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string"/>
                            <xs:element name="note" type="xs:string" minOccurs="0"/>
                            <xs:element name="quantity" type="xs:positiveInteger"/>
                            <xs:element name="price" type="xs:decimal"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="order-id" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>
Related