Using Gradle Dependency inside of Custom Plugin - maven

I am trying to write a custom Gradle Plugin that invokes the flyway migration using their API:
https://flywaydb.org/documentation/api/
This is a minimal example:
buildscript {
repositories.jcenter()
dependencies.classpath "org.flywaydb:flyway-core:4.1.2"
}
apply plugin: DatabaseHandlerPlugin
class DatabaseHandlerPlugin implements Plugin<Project> {
void apply(Project project) {
project.task("databaseHandler").doLast {
org.flywaydb.Flyway f = new Flyway(); // <= How can I use the above declared dependency here and in my projects?
}
}
}
But my gradle complains that it cannot load the Flyway class.

The Flyway class is in the org.flywaydb.core package. You missed the core bit. My full code that works:
import org.flywaydb.core.Flyway; // << can import here
buildscript {
repositories { mavenCentral() }
dependencies {
classpath "org.flywaydb:flyway-core:4.1.2"
}
}
apply plugin: DatabaseHandlerPlugin
class DatabaseHandlerPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('databaseHandler') {
doLast {
Flyway f = new Flyway()
println "Flyway: $f"
}
}
}
}
Output:
> gradle databaseHandler
:databaseHandler
Flyway: org.flywaydb.core.Flyway#7b27e8f4

Related

Export JaCoCo configuration to binary gradle plugin

How does one export JaCoCo configuration to a plugin which can be re-used in multiple projects?
import org.gradle.api.Plugin
import org.gradle.api.Project
class MyJacoco implements Plugin<Project> {
#Override
void apply(Project project) {
project.configure(project) {
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.8.0"
}
jacocoTestReport { // throws up on this
afterEvaluate {...}
group = "Reporting"
reports {...}
}
}
println(project.getPlugins().findPlugin('jacoco'))
}
}
In my projects I just want to use, when I publish...
apply plugin: MyJacoco
I've also tried How to configure Gradle Java plugin from a custom Gradle plugin but no results.

Kotlin Application with Gradle application plugin

I am trying to create a simple HelloWorld application using kotlin, gradle, and the gradle application plugin. When I run it with the below setup I get the following error:
Error: Main method is not static in class com.petarkolaric.helloworld.Main, please define the main method as:
public static void main(String[] args)
My build.gradle:
group 'helloworld'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = "com.petarkolaric.helloworld.Main"
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
My src/main/kotlin/com/petarkolaric/helloworld/Main.kt:
package com.petarkolaric.helloworld
class Main {
fun main(args : Array<String>) {
println("Hello, World!")
}
}
According to this blog post I should be able to use the application plugin this way.
What do I need to change to allow the application plugin to run my main function when I run gradle run?
As the error says, your main method is not static. You have the following options:
1) Put the main into the companion object and make it JvmStatic
class Main {
companion object {
#JvmStatic
fun main(args : Array<String>) {
println("Hello, World!")
}
}
}
2) Change your class to object - than you more or less have a singleton class and make it JvmStatic
object Main {
#JvmStatic
fun main(args : Array<String>) {
println("Hello, World!")
}
}
3) Place the main outside the class
fun main(args : Array<String>) {
println("Hello, World!")
}
class Main {
}

Gradle build with fatJar plugin and SpringBoot application gives 'Application startup failed'

Everything was working fine when starting my app using Intellij. But when I made fatJar (with gradle plugin: eu.appsatori.fatjar) and execute:
java -jar myapp.jar
I'm getting something like this:
11:41:01.224 [main] ERROR org.springframework.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [my.testing.MyAppMain]; nested exception is java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:482)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:184)
...
It looks like it didn't found auto configuration classes in META-INF/spring.factories.
How to add this file? And what should be the content of it?
I've got following build script:
apply plugin: "java";
apply plugin: "idea";
apply plugin: 'application'
apply plugin: 'eu.appsatori.fatjar'
apply plugin: 'org.springframework.boot'
repositories {
mavenCentral()
}
buildscript {
ext {
springBootVersion = '1.4.3.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/main/resources'
}
}
test {
java {
srcDir 'src/test/java'
}
}
}
fatJar {
manifest {
attributes("Main-Class": 'my.testing.MyAppMain')
}
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.RSA'
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-jdbc'
runtime 'mysql:mysql-connector-java'
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
And my example code is:
package my.testing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
#SpringBootApplication
public class MyAppMain {
private ConfigurableApplicationContext springContext;
#Autowired
private SimpleDao dao;
public static void main(String[] args) throws Exception {
MyAppMain test = new MyAppMain();
try {
test.init();
test.doWhatYouGotToDo();
} finally {
test.stop();
}
}
private void doWhatYouGotToDo() {
System.out.println("Auto-wired dao: " + dao.hashCode());
System.out.println("Auto-wired jdbcTemplate: " + dao.jdbcTemplate.hashCode());
}
private void init() throws Exception {
springContext = SpringApplication.run(MyAppMain.class);
springContext.getAutowireCapableBeanFactory().autowireBean(this);
}
private void stop() throws Exception {
springContext.close();
}
}
#Component
class SimpleDao {
#Autowired
JdbcTemplate jdbcTemplate;
}
application.properties file:
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/some_db?useSSL=false&serverTimezone=UTC
spring.datasource.username = some_user
spring.datasource.password = some_pass
NOTE: This question is based on SpringBoot - making jar files - No auto configuration classes found in META-INF/spring.factories
where are all answers are referring to building with Maven. Please put only answers related to Gradle here.
Although I mostly use Maven for Spring and Gradle for Android, but here is the gradle way for a Spring project:
gradle clean build
gradle bootRepackage
Result:
Here is my build.gradle file:

accessing the spring-restdocs generated content in a spring boot application

I'm using Spring Restdocs (v1.1.2) in a Spring Boot (v1.4.1) application.
In the jar task of the Gradle build file, I'm copying the generated output into public/docs:
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'public/docs'
}
}
and I see in the generated JAR the document in
BOOT-INF/classes/public/docs/api-guide.html
However, when I run the JAR, I can't seem to address the api-guide.html at /docs, /public/docs, etc.
Can someone please explain what I'm doing wrong?
Thanks!
--john
buildscript {
ext {
springBootVersion = '1.4.1.RELEASE'
}
}
plugins {
id "org.asciidoctor.convert" version "1.5.3"
}
apply plugin: 'groovy'
apply plugin: 'spring-boot'
ext {
snippetsDir = file('build/generated-snippets')
springRestdocsVersion = '1.1.2.RELEASE'
}
test {
outputs.dir snippetsDir
}
asciidoctor {
attributes 'snippets': snippetsDir
inputs.dir snippetsDir
dependsOn test
}
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'public/docs'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-rest')
testCompile("org.springframework.restdocs:spring-restdocs-mockmvc:${springRestdocsVersion}")
}
=============================================================
here's the application config:
#SpringBootApplication
#EnableJpaRepositories
#EnableScheduling
class Application {
static void main(String[] args) {
SpringApplication.run Application, args
}
}
and the test config:
#RunWith(SpringJUnit4ClassRunner)
#SpringApplicationConfiguration(classes = Application)
class ApplicationTests {
...
}
OK, I finally figured out what I was doing wrong. I had the spring-boot-actuator-docs enabled:
compile('org.springframework.boot:spring-boot-actuator-docs')
and it was "taking over" the /docs path. As soon as I relocated the generated restdocs to a different path, e.g.
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/api'
}
}
all was good.
Thanks Andy for your interest in my question and the very cool Spring REST Docs project!

How can I create file in my source directory project via custom gradle plugin?

I have next the default structure project:
src -> main -> java -> my package
And custom gradle plugin:
class CustomPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
project.task('createFile') << {
//Creating file in source directory
}
}
}
I want create file in my src directory when I call custom task via my gradle plugin. How to do it? Is it possible?
It will be:
apply plugin: 'java'
apply plugin: CustomPlugin
class CustomPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
project.task('createFile') << {
new File(project.file('src'), 'some-file').createNewFile()
}
}
}

Resources