Protocol-Buffers: How to exclude code generation during build time in gradle? - java

We have a few .proto files from which java classes are generated.
Because we have to keep the generated files in the repository, we would like to generate them only when we want (and not during every single build ). We are using this plugin. Also we would like to stick with this plugin, since we have quite a few things configured and we found it pretty useful.
Is there a way to exclude code generation during build task in gradle?

You can enable/disable protobuf tasks based on the property passed via command line:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.3'
}
}
apply plugin: 'java'
apply plugin: 'com.google.protobuf'
protobuf {
generateProtoTasks {
all().each { task ->
task.enabled = project.hasProperty('runProtobuf')
}
}
}
afterEvaluate {
println "generateProto enabled ${tasks.generateProto.enabled}"
println "generateTestProto enabled ${tasks.generateTestProto.enabled}"
}

Related

Create Jar from Checker Framework enabled build?

I'm adding Checker Framework to an existing Java Gradle build. I have Checker integrated and raising issues and that's all working great. But now that I've added it, my build is no longer producing a .jar file as it once did.
Previously, I'd get a .jar at build/libs/myproject.jar. Now instead I see build/checkerframework and build/main but no build/libs and no .jar.
My build.gradle is below. Anyone attempted this before? Any success?
I guess I'd also accept an answer that shows how run Checker outside of the build, e.g. gradle check to run a build with Checker, and gradle build to produce a .jar. But I'd really prefer to have just a single build step if at all possible.
Thanks!
plugins {
id "org.checkerframework" version "0.5.18"
id 'application'
}
apply plugin: 'org.checkerframework'
checkerFramework {
checkers = [
'org.checkerframework.checker.nullness.NullnessChecker',
'org.checkerframework.checker.units.UnitsChecker'
]
}
repositories {
jcenter()
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
// Embed all dependencies to create a "fat jar" as required for AWS deployment.
// Exclude 3rd-party signing files to prevent security errors at runtime
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
manifest {
attributes('Main-Class': 'client.CliMain')
}
}
If the build is passing, then adding -processor should not affect whether a .jar file is produced. (Unless you pass -proc:only or the like.)
If the build is failing, then Gradle won't build the jar files.
You said the Checker Framework is "raising issues", so maybe the build is failing.

How to simulate a gradle build script in junit test?

I am playing a little bit with my own gradle plugin (for gradle 6.5.1). Now I wrote a small test (implemented in java) which is not working:
Project project = ProjectBuilder.builder().build();
ScriptHandler buildscript = project.getBuildscript();
Action<? super MavenArtifactRepository> action = new Action<MavenArtifactRepository>() {
#Override
public void execute(MavenArtifactRepository mavenArtifactRepository) {
mavenArtifactRepository.setUrl("https://plugins.gradle.org/m2/");
}
};
buildscript.getRepositories().maven(action);
buildscript.getDependencies().add("classpath", "io.spring.gradle:dependency-management-plugin:1.0.9.RELEASE");
project.getPlugins().apply("java");
project.getPlugins().apply("io.spring.dependency-management");
It says Plugin with id 'io.spring.dependency-management' not found. I thought that I copied the original from https://plugins.gradle.org/plugin/io.spring.dependency-management
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.9.RELEASE"
}
}
apply plugin: "io.spring.dependency-management"
But I guess thats not the case. :-) Any idea how to translate that snippet to java world?
If you want to apply an other plugin in your test you need the other plugin on your classpath. So you have to add to the build file of your gradle-plugin and than its there.
In this case it means write the following to your build.gradle
testImplementation "io.spring.gradle:dependency-management-plugin:1.0.9.RELEASE"

Running Flyway migrations on gradle refresh

I am still trying to wrap my head around gradle so please bear with me.
I'm trying to set up flyway migrations to run automatically on every gradle refresh/build instead of having to run a command-line command. So when someone is pulling the latest changes including some new migrations their local db will be up to date.
I have this build.grade in the root dir:
buildscript {
...
repositories {
mavenLocal()
mavenCentral()
}
allprojects {
...
}
project(":core") {
apply plugin: "java"
dependencies {
compile project(":shared")
}
}
project(":server") {
apply plugin: "java"
dependencies {
compile project(":shared")
}
}
project(":shared") {
apply plugin: "java"
}
tasks.eclipse.doLast {
delete ".project"
}
Where I've tried merging the lines from the flyway get started pages.
I basically want to run the $ gradle flywayMigrate -i command from within the build.gradle file. I've tried with build.finalizedBy(flywayMigrate) but to no avail.
How would I do something like that?
Thanks in advance!
In order to make build finalized by flywayMigrate you need to run gradle build which probably You didn't.
To run flywayMigrate you can use defaultTasks which will run the tasks configured if no other are provided. So:
buildscript {
dependencies {
classpath 'com.h2database:h2:1.4.191'
}
}
plugins {
id "org.flywaydb.flyway" version "4.1.2"
}
flyway {
url = 'jdbc:h2:file:./target/foobar'
user = 'sa'
}
defaultTasks 'flywayMigrate'
When it comes to configuring -i (logging level) from within build.gradle it seems to be impossible with the newest gradle versions.

Compiling GRPC server/client

I'm having a lot of trouble figuring out how to compile a GRPC Java server. I looked all over the grpc.io website and closest thing I found was this: http://www.grpc.io/docs/#quick-start , where I run
../gradlew -PskipCodegen=true installDist to build, and
./build/install/grpc-examples/bin/hello-world-client to run the client. This all works, but only for the hello-world tutorial. I have no idea how to do this for my own client/server. I'm able to generate the client/server protobufs using the .proto file. I looked in their readme and Java tutorial and couldn't find out how to compile the actual server (and client) after I write them
https://github.com/grpc/grpc-java/blob/master/examples/README.md
(can't link java tutorial because I dont have enough reputation). Unless there's documentation im missing, does anyone know how to compile a server and client that implements the GRPC classes generated from the .proto file? I did spend a fair amount of time searching. Any advice is much appreciated, thanks.
Also have a similar problem, ensure that:
You configured correctly the protoc, that will be downloading the executable and configure it as an environment variable of your OS.
The build.gradle file, make sure to include protobuf-gradle-plugin:
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'com.google.protobuf'
ext.grpcVersion = '1.0.1'
ext.protobufVersion = '3.0.2'
buildscript {
repositories { mavenCentral() }
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' }
}
repositories {
mavenCentral()
}
dependencies {
compile "com.google.protobuf:protobuf-java:${protobufVersion}"
compile "io.grpc:grpc-all:${grpcVersion}"
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protobufVersion}" }
plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } }
generateProtoTasks { ofSourceSet('main')*.plugins { grpc { } } }
}
idea {
module {
sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java");
sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/grpc");
}
}
Your proto file:
syntax = "proto3";
package com.company.project;
service CompanyService{
rpc call(RequestMessage) returns (ResponseMessage) {}
}
Run gradle clean build, and it should generate your service and client classes for CompanyService.
The idea plugin, is jut for telling IntelliJ to recognize the src/main/proto as a source set.
To actually execute the client and server, you will need to make the implementation, mentioned in the tutorial for gRpc, and then apply the application plugin, in order to generate correctly the executable jar
//build.grdle code...
apply plugin: 'application'
mainClassName = 'com.company.project.MainClass'
jar { manifest { attributes('Main-Class' : mainClassName) } }
I had a similar issue but solved it using it in Gradle by adding the 'application' plugin. Before I was using the 'java' plugin and I could only generated a jar file. After switching to the 'application' plugin there is a gradle task similar to the gRPC example.
./gradlew installDist
And now to start your server you can run something similar to this:
./build/install/your-project/bin/your-server
To actually generate the Java classes off my .proto files I needed to run './gradle build' and also include the source generated using the sourceDir element you can see in the build.gradle below.
This is the full build.gradle file.
apply plugin: 'application'
apply plugin: 'com.google.protobuf'
apply plugin: 'idea'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.6'
}
}
repositories {
jcenter()
}
dependencies {
compile 'io.grpc:grpc-all:0.14.0'
}
mainClassName = "com.domain.service.YourMainClass"
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.0.0-beta-2"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:0.14.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
idea {
module {
sourceDirs += file("${projectDir}/build/generated/source/proto/main/grpc");
sourceDirs += file("${projectDir}/build/generated/source/proto/main/java");
}
}
I am new to gRPC so any improvments to my Gradle file would be appericated.
This question has been answered on groups.google.com by 'Eric Anderson':
The JAR only has your code in it. It sounds like you want to make a "fat" jar which includes all your dependencies. You can do something like this:
jar {
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
Note that that isn't gRPC-specific; it's just working with Gradle. There may be alternatives, such as a quick Googling returned gradle-fatjar-plugin.

Dagger 2.0 - AppEngine - gradle configuration

I am trying to move from Dagger 1.2.2 to Dagger 2.0.1 in AppEngine project (NOT Android one).
With Dagger 1.2.2 simple:
compile 'com.squareup.dagger:dagger-compiler:1.2.2'
compile 'com.squareup.dagger:dagger:1.2.2'
did the trick.
With Dagger 2.0.1:
compile 'com.google.dagger:dagger-compiler:2.0.1'
compile 'com.google.dagger:dagger:2.0.1'
does not work (source is generated but mixed up with *.class files in build/classes/main/..package../).
You can also do it without net.ltgt.apt plugin, (which by the way may conflict with lombok).
apply plugin: 'java'
apply plugin: 'idea'
def generatedMain = new File(buildDir, "generated/main")
compileJava {
doFirst {
generatedMain.mkdirs()
}
options.compilerArgs += ['-s', generatedMain]
}
idea.module.sourceDirs += generatedMain
dependencies {
compileOnly 'com.google.dagger:dagger-compiler:2.8'
compile 'com.google.dagger:dagger:2.8'
}
I've found a solution.
https://github.com/tbroyer/gradle-apt-plugin
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "net.ltgt.gradle:gradle-apt-plugin:0.3"
}
}
apply plugin: "net.ltgt.apt"
dependecies {
apt 'com.google.dagger:dagger-compiler:2.0.1'
compile 'com.google.dagger:dagger:2.0.1'
}
Additionally if you are using Intellij a following configuration is recommended:
When using the Gradle integration in IntelliJ IDEA however, rather
than the idea task, you'll have to manually enable annotation
processing: in Settings… → Build, Execution, Deployment → Compiler →
Annotation Processors, check Enable annotation processing and Obtain
processors from project classpath. To mimic the Gradle behavior and
generated files behavior, you can configure the production and test
sources directories to build/generated/source/apt/main and
build/generated/source/apt/test respectively and choose to Store
generated sources relative to: Module content root.
I've also had to remove Exclude from whole build directory and mark generated/source/apt/main directory as source.

Categories