I am having trouble importing Protobuf generated classes using Gradle.
This is how my project tree looks like:
I've tried marking the packages as Source, I have tried all possible combinations of imports:
import generated.main.grpc.GreeterGrpc;
import main.java.HelloRequest;
import java.*;
import HelloRequest;
None of them works. Here is my build.gradle:
group 'andu'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'com.google.protobuf'
sourceCompatibility = 1.5
repositories {
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'io.grpc:grpc-protobuf:1.0.0-pre2'
compile 'com.google.protobuf:protobuf-java:3.0.0'
compile 'io.grpc:grpc-stub:1.0.0-pre2'
compile 'io.grpc:grpc-netty:1.3.0'
compile 'io.grpc:grpc-protobuf:1.3.0'
compile 'io.grpc:grpc-stub:1.3.0'
}
sourceSets {
main {
proto {
srcDir 'src/main/proto'
}
java {
srcDirs = ['src/main/java', 'generated/main/java']
}
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.2.0"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.3.0'
}
}
generateProtoTasks.generatedFilesBaseDir = 'generated'
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
Before I added
generateProtoTasks.generatedFilesBaseDir = 'generated'
all of my generated classes would be added to build/generated/main/java
from : https://medium.com/#DivyaJaisawal/generate-java-code-from-proto-file-using-gradle-1fb9fe64e046
The Protobuf plugin assumes Protobuf files (*.proto) are organized in the same way as Java source files, in sourceSets. The Protobuf files of a sourceSet are compiled in a single protoc run, and the generated files are added to the input of the Java compilation run of that sourceSet ().
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
It may be a little different since I did this in an Android project, but what worked for me was adding classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.1" in my root build.gradle and the following in the apps build.gradle.
Also don't forget to run a gradle build as only running won't generate the classes automatically unless you have the build project automatically option selected in compiler options.
apply plugin: 'com.google.protobuf'
protobuf {
generatedFilesBaseDir = "$projectDir/generated"
protoc {
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
javalite {
artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
}
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.0.3'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
java
}
task.plugins {
grpc {}
}
}
}
}
//Protobuf
compile 'com.google.protobuf:protobuf-lite:3.0.0'
compile 'com.google.protobuf:protobuf-java:3.0.0'
//GRPC
compile('io.grpc:grpc-protobuf:1.1.1') {
exclude module: 'jsr305'
}
compile('io.grpc:grpc-okhttp:1.1.1') {
exclude module: 'jsr305'
}
compile('io.grpc:grpc-stub:1.1.1') {
exclude module: 'jsr305'
}
I've also made two basic but working examples using gRPC that may be able to help. Example Java project using Maven (if you're open to switching to Maven). And a basic Example Android project using gradle although there are minor differences (I'm using java-lite and okhttp instead of netty).
I had same issues in intellij while in sbt everything worked just fine, its just problem of higlightning it in IDE. I had to go to 'Project structure'->'Modules'->click on 'root'-> 'Depencencies'->'+' sign at the bottom-> Jars or directories -> add your generated dir as dependency.
If you want to generate for java, you have to mention a package name in your proto file like this:
option java_package = "com.example";
Do that and generate again.
Now import like this:
`import com.example.HelloRequest;`
Related
I'm trying to build a jar for a custom gradle plugin to be used by other gradle projects. I'm using java to write the plugin. I'm having a problem including dependencies in my jar. If I build the jar using the below build.gradle
plugins {
id 'groovy'
}
repositories{
mavenCentral()
}
dependencies {
compile gradleApi()
compile localGroovy()
compile 'com.google.guava:guava:27.0-jre'
testCompile 'junit:junit:4.12'
//compile 'org.apache.commons:commons-lang3:3.8.1'
}
group = 'com.mine'
version = '1.0'
I get a NoClassDefFound exception for guava classes when applying the plugin on a project. If I include a task to create a jar with dependencies like below in the build.gradle
jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)}
}
}
It says Plugin with Id 'my-plugin' not found. How do I include dependencies in a gradle plugin jar?
Your plugin project should be configured as a standalone Plugin project and then published to a maven repository, which will make dependencies resolution work; there is good documentation about writing custom plugin here, specially the following part : using Gradle plugin development plugin
There is also a good example of writing/publishing/consuming a custom Plugin in the Gradle examples here : https://github.com/gradle/gradle/tree/master/subprojects/docs/src/samples/plugins (see the two subprojects publishing and consuming )
And here is a working example with a plugin that has dependency on external library (commons-lang for example):
Plugin project
build.gradle
plugins {
id 'java-gradle-plugin'
id 'groovy'
id 'maven-publish'
}
group 'org.gradle.sample.plugin'
version '0.1'
// pugin metadata configuration
gradlePlugin {
plugins {
myplugin {
id = "org.gradle.sample.plugin.myplugin"
implementationClass = "org.gradle.sample.plugin.MyPlugin"
}
}
}
// publish to local maven repo for testing
publishing {
repositories {
maven {
url "../repos/maven-repo"
}
}
}
// repo for dependences resolution
repositories{
jcenter()
}
// dependencies of this plugin
dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
}
Plugin implementation : src/main/groovy/org/gradle/sample/plugin/MyPLugin.groovy
package org.gradle.sample.plugin
import org.apache.commons.lang3.StringUtils
import org.gradle.api.Plugin
import org.gradle.api.Project
class MyPlugin implements Plugin<Project> {
#Override
void apply(final Project project) {
println "Applying custom plugin... "
project.tasks.create('testPlugin'){
doLast{
println " custom plugin task executing."
println "Result: " + StringUtils.capitalize("stringtotest")
}
}
}
}
Build and publish this plugin ./gradlew publish : the plugin jar and "plugin marker artefacts" will be published to local maven repo in ../repos/maven-repo
Consumer project
build.gradle
plugins {
id 'java'
// import/apply your custom plugin
id 'org.gradle.sample.plugin.myplugin' version '0.1'
}
group 'org.gradle.sample.plugin'
version '0.1'
repositories{
maven {
url "../repos/maven-repo"
}
jcenter()
}
To test the plugin, try to execute the plugin task testPlugin
> Task :testPlugin
custom plugin task executing.
Result: Stringtotest
Sorry to add this as an answer but I don't have enough points to comment (yes it is a bit late in coming but I found this in a search and it came so close, maybe this will help someone else).
The answer by #M.Ricciuti is correct, just missing one file, namely a settings.gradle in the referencing project (not the plugin) directory:
pluginManagement {
repositories {
maven {
url '../repos/maven-repo'
}
gradlePluginPortal()
ivy {
url '../repos/ivy-repo'
}
}
}
Many thanks, I have tried many things that didn't work before finding this, even the examples by gradle didn't work (or more likely I didn't run them correctly). Anyway I merged what I saw in the answers with M. Ricciuti's answer and saw that file in the sample.
My complete project is at https://github.com/reddierocket/sampleGradlePlugin
The readme has instructions to run it. (Note I did not include the wrapper but I am using gradle version 5.3.1.)
Adding clojure to an already existing gradle java project
I have a Java project that I want to start trying to add some Clojure to, but I'm hitting a few issues. I'm using the IntelliJ IDEA with the Cursive for Clojure IntelliJ plugin.
I am also using the gradle-clojure plugin for Clojure. My Java classes recognise and can call my Clojure code, but my Java code will no longer compile because at compile time it can no longer see my Clojure code.
Do I need to add an extra step in my build.gradle? Do I need to compile my Clojure separate and manually before trying to compile Java?
Any help would be greatly appreciated.
Environment
gradle-clojure v0.3.1 gradle v4.4.1Java v1.8 Intellij IDE on MacOS High Sierra
Stacktrace <> Task :compileJava FAILED java:8: error: cannot find symbol import com.example.clojure;
You can use Netflix's Clojure Wrapper, nebula.clojure.
Here is an example of a Gradle Build script for a project that uses Java and Clojure:
buildscript {
ext {
springBootVersion = '1.5.8.RELEASE'
}
repositories {
jcenter()
maven { url 'http://clojars.org/repo' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "com.netflix.nebula:nebula-clojure-plugin:4.4.0"
}
}
plugins {
id "nebula.clojure" version "4.4.0"
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'application'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group 'com.demo'
def artifactName = 'demo-service'
version = latestRepoTag()
static def latestRepoTag() {
def cmd = "git describe --abbrev=0"
def proc = cmd.execute();
return proc.text.trim();
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
ext['spring-restdocs.version'] = '1.2.1.RELEASE'
ext {
springCloudVersion = 'Dalston.SR4'
}
compileJava {
classpath = project.files(
project.compileClojure.outputs,
classpath
)
}
compileClojure {
jvmOptions {
jvmArgs '-Djava.awt.headless=true'
}
}
repositories {
jcenter()
maven { url 'http://clojars.org/repo' }
}
jar {
baseName = "${artifactName}"
version = latestRepoTag()
}
clojure.aotCompile = true
configurations{
dev
}
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR3'
}
}
dependencies {
compile 'org.clojure:clojure:1.6.0'
compile('com.google.guava:guava:19.0')
compile("commons-io:commons-io:2.5")
compile "org.apache.pdfbox:pdfbox:2.0.0-RC3"
compile("org.apache.commons:commons-lang3:3.0")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-jdbc")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.cloud:spring-cloud-starter-eureka")
compileOnly("org.projectlombok:lombok:1.16.6")
runtime('com.h2database:h2:1.4.190')
runtime("com.ingres.jdbc:iijdbc:10.0-4.0.5")
runtime('org.apache.commons:commons-dbcp2:2.1.1')
runtime('org.postgresql:postgresql:9.4.1209')
dev("org.springframework.boot:spring-boot-devtools")
testCompile('com.jayway.jsonpath:json-path')
testCompile('com.jayway.jsonpath:json-path-assert:2.2.0')
testCompile('com.google.code.gson:gson:2.8.1')
testCompile("org.springframework.boot:spring-boot-starter-test")
testCompile("org.springframework.restdocs:spring-restdocs-mockmvc:1.2.1.RELEASE")
}
task wrapper(type: Wrapper) {
gradleVersion = '4.1'
}
bootRun {
classpath = sourceSets.main.runtimeClasspath + configurations.dev
systemProperties = System.properties
jvmArgs = ["-client", "-Dsun.net.inetaddr.ttl=60", "-Djava.security.egd=file:/dev/./urandom"]
environment = [
'spring_profiles_active': 'beta,fast_discovery'
]
}
Here is a link to the plugin on Gradle's plugin documentation site:
I'm trying to make a gradle script to upload some data on build with firebase. But I'm getting a strange error from the Firebase Java Admin SDK:-
Caused by: java.lang.NoSuchMethodError: org.json.JSONObject.<init>(Ljava/lang/String;)V
at com.google.firebase.auth.FirebaseCredentials$CertCredential.<init>(FirebaseCredentials.java:273)
at com.google.firebase.auth.FirebaseCredentials.fromCertificate(FirebaseCredentials.java:156)
at com.google.firebase.auth.FirebaseCredentials.fromCertificate(FirebaseCredentials.java:130)
at com.google.firebase.auth.FirebaseCredentials$fromCertificate.call(Unknown Source)
at eu.long1.jwnotes.gradleplugins.UploadTask.action(UploadTask.groovy:31)
The task this like this:
class UploadTask extends DefaultTask {
String message = "Huray!"
#TaskAction
def action() {
String a = "private-key"
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(new ByteArrayInputStream(a.getBytes("UTF-8"))))
.setDatabaseUrl("https://jwnotes.firebaseio.com/")
.build()
FirebaseApp.initializeApp(options)
FirebaseDatabase.getInstance().getReference().child("alfa-gradle").setValue(message)
}
}
I'm getting the error when I'm trying to apply to run the task.
UPDATE
this is my plugin gradle file:
plugins {
id 'groovy'
id 'maven'
}
group 'eu.long1.jwnotes.gradleplugins'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
compile gradleApi()
compile localGroovy()
}
dependencies {
compile 'com.google.firebase:firebase-admin:5.3.1'
compile 'org.json:json:20160810'
}
sourceCompatibility = 1.8
jar {
into('lib') {
from 'lib'
}
}
Your runtime environment is picking up another version of org.json:json library that is not compatible with the Firebase SDK. You need to make sure it uses the correct version of the json library. This generally requires inspecting the dependency tree, and putting an explicit exclude for some unnecessary dependencies.
Update
Following worked for me:
buildscript {
repositories {
maven {
mavenCentral()
url uri('repo')
}
}
dependencies {
classpath group: 'net.hkj', name: 'gradle-task',
version: '1.0-SNAPSHOT'
}
dependencies {
classpath 'com.google.firebase:firebase-admin:5.3.1'
}
}
task greeting(type: net.hkj.UploadTask) {
}
I have the jar containing the compiled task in the repo directory. I put your task implementation into a src/main/groovy/net/hkj/UploadTask.groovy file, and compiled the output into the repo directory, before invoking the greeting task.
We are starting a new Project with gradle (all of my previous projects are on Maven) and this is my first experience on using gradle, below is my build.gradle file and am trying to compile the java and groovy sources using the task compile
buildscript {
ext {
springBootVersion = '1.5.2.RELEASE'
springVersion = '4.3.7.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'groovy'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
task compile(type: GroovyCompile) {
//source = fileTree(dir: 'src', include: '**/*.java')
sourceSets {
main {
java { srcDirs = [] } // no source dirs for the java compiler
groovy { srcDir "src" } // compile everything in src/ with groovy
}
}
destinationDir = file('build/classes/main')
classpath = files('build/classes/main')
}
dependencies {
compile "org.codehaus.groovy:groovy-all:2.4.10"
compile('org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}')
compile('org.springframework.boot:spring-boot-actuator-docs:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-groovy-templates:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-jdbc:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-jersey:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-security:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-web:${springBootVersion}')
compile('org.springframework:spring-webmvc:${springVersion}')
compile "com.microsoft:sqljdbc4:4.0"
testCompile('org.springframework.boot:spring-boot-starter-test:${springBootVersion}')
}
And when I run the gradle compile command am seeing :compile NO-SOURCE and no compiled classes in build\classes\main
can someone please help me with gradle task to compile both java and groovy sources?
The Gradle docs of the Groovy plugin describe the default layout like follows. If it is an option to stick to that, there is no need for a custom compile task.
src/main/java Production Java source
src/main/resources Production resources
src/main/groovy Production Groovy sources. May also contain Java sources for joint compilation.
src/test/java Test Java source
src/test/resources Test resources
src/test/groovy Test Groovy sources. May also contain Java sources for joint compilation.
```
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.