Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

com.google.protobuf.GeneratedMessageV3.isStringEmpty should be public #9236

Closed
ochinchina opened this issue Nov 22, 2021 · 16 comments
Closed

Comments

@ochinchina
Copy link

Version: v3.19.1
Language: Java
OS: Windows 10

When compiling the protoc 3.19.1 generated java source codes from a .proto file, following error is raised:

 error: cannot find symbol
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(appId_)) {
                                               ^
  symbol:   method isStringEmpty(Object)
  location: class GeneratedMessageV3

After checking the source code of the java class com.google.protobuf.GeneratedMessageV3 and found the method isStringEmpty is defined as protected instead of public.

@elharo
Copy link
Contributor

elharo commented Nov 22, 2021

What file is the error found in? Do you have the complete source code of that file handy?

@ochinchina
Copy link
Author

detailed steps for re-produce this bug:

  1. download the protoc v3.19.1 from https://github.com/protocolbuffers/protobuf/releases/download/v3.19.1/protoc-3.19.1-linux-x86_64.zip
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.1/protoc-3.19.1-linux-x86_64.zip
  1. unzip the downloaded protoc
$ unzip protoc-3.19.1-linux-x86_64.zip
$ cd protoc-3.19.1
  1. compile the following helloworld.proto
syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

with command:

$ mkdir java_output
$ bin/protoc --java_output=java_output helloworld.proto

go to the directory java_output/io/grpc/examples/helloworld and grep the com.google.protobuf.GeneratedMessageV3.isStringEmpty

$ cd java_output/io/grpc/examples/helloworld
$ grep com.google.protobuf.GeneratedMessageV3.isStringEmpty *.java
HelloReply.java:    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(message_)) {
HelloReply.java:    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(message_)) {
HelloRequest.java:    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
HelloRequest.java:    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {

The protected method isStringEmpty in class com.google.protobuf.GeneratedMessageV3 is used by class HelloReply and HelloRequest. When trying to compile the above generated source code, we get the error:

 error: cannot find symbol
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(appId_)) {
                                               ^
  symbol:   method isStringEmpty(Object)
  location: class GeneratedMessageV3

@perezd
Copy link
Contributor

perezd commented Nov 23, 2021

Can you confirm you're using the newest runtime when compiling the source code produced by that version of protoc? I think we've seen a similar issue in the past.

@toffentoffen
Copy link

I've experienced a similar issue will trying to use the latest version of protoc, protbuf-java and grpc-java to being able to compile the protos in a Mac M1 trough the protobuf maven plugin.

com.google.protobuf.protoc = 3.19.1
protoc-gen-grpc-java.plugin = 1.42.1 (has an internal dependency on protobuf-java = 3.17.2) (does not contain com.google.protobuf.GeneratedMessageV3.isStringEmpty)
protobuf-java = 3.19.1
protobuf-java-util = 3.19.1

The problem is that the latest protoc generates code that depends on function (com.google.protobuf.GeneratedMessageV3.isStringEmpty) that are available from 3.17.3+.

So, as @perezd said, probably your compiling agains an older version of protobuf-java.

So a workaround would be using protoc 3.17.3 as I've mentioned #8062 (comment) and grpc/grpc-java#8724 (where if also asked to upgrade to the latest protobuf 3.19.1 release)

toffentoffen added a commit to toffentoffen/skywalking that referenced this issue Nov 26, 2021
…c M1

Upgrade to the latest grpc-java 1.42.1 which is only compatible and [tested against](grpc/grpc-java#8551 (comment)) 3.17.2, but we can assume that 3.17.3 (which has osx-aarch_64 compatible maven artifacts) is save to use.

We could have also upgrade to the latest grpc-java 1.42.1 and latest protoc 3.19.1, but it can not be directly done, it needs to tweak the grpcs-java internal dependencies. So we choose the safest option and discarded this option because of the following reasons:
 - Protoc 3.19.1 generates code that relies on methods not available in protobuf-java 3.17.2 ([“issue”](protocolbuffers/protobuf#9236 (comment))) (which java-grpc relies on). So we need to tell grpc-java via dependency management to use 3.19.1 instead of 3.17.2.

Signed-off-by: Marc Navarro Sonnenfeld <marcnavarro@tetrate.io>
toffentoffen added a commit to toffentoffen/skywalking that referenced this issue Nov 26, 2021
…c M1

Upgrade to the latest grpc-java 1.42.1 which is only compatible and [tested against](grpc/grpc-java#8551 (comment)) 3.17.2, but we can assume that 3.17.3 (which has osx-aarch_64 compatible maven artifacts) is save to use.

We could have also upgrade to the latest grpc-java 1.42.1 and latest protoc 3.19.1, but it can not be directly done, it needs to tweak the grpcs-java internal dependencies. So we choose the safest option and discarded this option because of the following reasons:
 - Protoc 3.19.1 generates code that relies on methods not available in protobuf-java 3.17.2 ([“issue”](protocolbuffers/protobuf#9236 (comment))) (which java-grpc relies on). So we need to tell grpc-java via dependency management to use 3.19.1 instead of 3.17.2.

Signed-off-by: Marc Navarro Sonnenfeld <marcnavarro@tetrate.io>
toffentoffen added a commit to toffentoffen/skywalking that referenced this issue Nov 26, 2021
…c M1

Upgrade to the latest grpc-java 1.42.1 which is only compatible and [tested against](grpc/grpc-java#8551 (comment)) 3.17.2, but we can assume that 3.17.3 (which has osx-aarch_64 compatible maven artifacts) is save to use.

We could have also upgrade to the latest grpc-java 1.42.1 and latest protoc 3.19.1, but it can not be directly done, it needs to tweak the grpcs-java internal dependencies. So we choose the safest option and discarded this option because of the following reasons:
 - Protoc 3.19.1 generates code that relies on methods not available in protobuf-java 3.17.2 ([“issue”](protocolbuffers/protobuf#9236 (comment))) (which java-grpc relies on). So we need to tell grpc-java via dependency management to use 3.19.1 instead of 3.17.2.

Signed-off-by: Marc Navarro Sonnenfeld <marcnavarro@tetrate.io>
wu-sheng pushed a commit to apache/skywalking that referenced this issue Nov 26, 2021
…c M1 (#8186)

Upgrade to the latest grpc-java 1.42.1 which is only compatible and [tested against](grpc/grpc-java#8551 (comment)) 3.17.2, but we can assume that 3.17.3 (which has osx-aarch_64 compatible maven artifacts) is save to use.

We could have also upgrade to the latest grpc-java 1.42.1 and latest protoc 3.19.1, but it can not be directly done, it needs to tweak the grpcs-java internal dependencies. So we choose the safest option and discarded this option because of the following reasons:
 - Protoc 3.19.1 generates code that relies on methods not available in protobuf-java 3.17.2 ([“issue”](protocolbuffers/protobuf#9236 (comment))) (which java-grpc relies on). So we need to tell grpc-java via dependency management to use 3.19.1 instead of 3.17.2.

Signed-off-by: Marc Navarro Sonnenfeld <marcnavarro@tetrate.io>
aherrmann-da pushed a commit to digital-asset/daml that referenced this issue Dec 2, 2021
The latest version of rules_haskell pins protoc to 3.19.1. However, this
generates code that also requires a more recent version of the Java
proto libraries. This change pins the protoc version at the same version
as the protobuf-java library, see protocolbuffers/protobuf#9236.
aherrmann-da added a commit to digital-asset/daml that referenced this issue Dec 2, 2021
* Update rules_haskell

changelog_begin
changelog_end

* Use mostly deterministic distdir path

changelog_begin
changelog_end

Use a path for distdir in the `haskell_cabal_*` rules that is based on
the package name and deterministic unless there is a collision with an
already existing file or directory.

The distdir path enters flags that are passed to GHC and thereby enters
the 'flag hash' field of the generated interface files. If the distdir
path is indeterministic, then the interface file will also be
indeterministic.

* Pin com_google_protobuf to 3.17.3

The latest version of rules_haskell pins protoc to 3.19.1. However, this
generates code that also requires a more recent version of the Java
proto libraries. This change pins the protoc version at the same version
as the protobuf-java library, see protocolbuffers/protobuf#9236.

Co-authored-by: Andreas Herrmann <andreas.herrmann@tweag.io>
@Tridu33
Copy link

Tridu33 commented Dec 9, 2021

protobuf has changed in the new version, and configure work here:

    <dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.19.1</version> 
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <extensions>true</extensions>
                <configuration>
                    <protoSourceRoot>${project.basedir}/proto</protoSourceRoot>
                    <outputDirectory>${project.build.sourceDirectory}</outputDirectory>
                    <clearOutputDirectory>true</clearOutputDirectory>
                    <temporaryProtoFileDirectory>
                        ${project.build.directory}/protoc-temp
                    </temporaryProtoFileDirectory>
                    <protocExecutable>
                        D:/arch/myexe/protoc/bin/protoc.exe <!-- libprotoc 3.19.1 -->
                    </protocExecutable>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

@elharo
Copy link
Contributor

elharo commented Dec 9, 2021

Just a = guess: there is no official protobuf maven plugin and the one you're using here is several versions behind what that developer has released. It could be that the old version of this plugin is pulling in older versions of the proto library.

@ricardoseb
Copy link

To solve this issue, you must explicitly indicate the version of protobuf-java(3.17.3+), for example in your build.gradle file:
implementation 'com.google.protobuf:protobuf-java:3.19.1'

@gregorypa
Copy link

I succeeded to compile protobuf after following instructions from here - https://github.com/grpc/grpc-java

@elharo
Copy link
Contributor

elharo commented Dec 20, 2021

Thanks, good to hear

@EasyG0ing1
Copy link

EasyG0ing1 commented Jan 5, 2022

@elharo I've been trying to teach myself how to code and decode protocolbuffers because of a specific need I have to be able to migrate GoogleAuthenticator app exports into an app that I'm writing in Java. My search to learn how to do this led me to this Issue on Github - where the solution was not one that I understood at all ... which started my pursuit to understand how to do this stuff ... that Issue has a .proto file listed as one that will work to accomplish the task. Here is the .proto file:

syntax = "proto3";

message MigrationPayload {
	enum Algorithm {
		ALGORITHM_UNSPECIFIED = 0;
		ALGORITHM_SHA1 = 1;
		ALGORITHM_SHA256 = 2;
		ALGORITHM_SHA512 = 3;
		ALGORITHM_MD5 = 4;
	}
	enum DigitCount {
		DIGIT_COUNT_UNSPECIFIED = 0;
		DIGIT_COUNT_SIX = 1;
		DIGIT_COUNT_EIGHT = 2;
	}
	enum OtpType {
		OTP_TYPE_UNSPECIFIED = 0;
		OTP_TYPE_HOTP = 1;
		OTP_TYPE_TOTP = 2;
	}
	message OtpParameters {
		bytes secret = 1;
		string name = 2;
		string issuer = 3;
		Algorithm algorithm = 4;
		DigitCount digits = 5;
		OtpType type = 6;
		int64 counter = 7;
	}
	repeated OtpParameters otp_parameters = 1;
	int32 version = 2;
	int32 batch_size = 3;
	int32 batch_index = 4;
	int32 batch_id = 5;
}

I then found this tutorial on Google for protocol buffers, which instructed me to download the proto command which ultimately led me here to get the compiled version for MacOS.

I then ran the command and received a generated .java class file which has multiple places in it with these statements in it:

com.google.protobuf.GeneratedMessageV3.isStringEmpty

But 'isStringEmpty' seems to be a reference to something that does not exist...

From where I stand, the proto command that generates the .java class is the point where this is failing as it seems to be inserting code into the class that it generates that makes calls to another class that do not exist.

What I would like to know ... is how do I fix the class that it generated?

This is the dependency that I'm using in my project by the way:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.19.1</version>
</dependency>

Edit:

When I downloaded proto version 3.17.3 from here and re-generated the class from that same .proto file, the resulting class did not contain the call to isStringEmpty and caused no errors while still using dependency version 3.19.1.

@rafaribe
Copy link

rafaribe commented Jan 6, 2022

@elharo I've been trying to teach myself how to code and decode protocolbuffers because of a specific need I have to be able to migrate GoogleAuthenticator app exports into an app that I'm writing in Java. My search to learn how to do this led me to this Issue on Github - where the solution was not one that I understood at all ... which started my pursuit to understand how to do this stuff ... that Issue has a .proto file listed as one that will work to accomplish the task. Here is the .proto file:

syntax = "proto3";

message MigrationPayload {
	enum Algorithm {
		ALGORITHM_UNSPECIFIED = 0;
		ALGORITHM_SHA1 = 1;
		ALGORITHM_SHA256 = 2;
		ALGORITHM_SHA512 = 3;
		ALGORITHM_MD5 = 4;
	}
	enum DigitCount {
		DIGIT_COUNT_UNSPECIFIED = 0;
		DIGIT_COUNT_SIX = 1;
		DIGIT_COUNT_EIGHT = 2;
	}
	enum OtpType {
		OTP_TYPE_UNSPECIFIED = 0;
		OTP_TYPE_HOTP = 1;
		OTP_TYPE_TOTP = 2;
	}
	message OtpParameters {
		bytes secret = 1;
		string name = 2;
		string issuer = 3;
		Algorithm algorithm = 4;
		DigitCount digits = 5;
		OtpType type = 6;
		int64 counter = 7;
	}
	repeated OtpParameters otp_parameters = 1;
	int32 version = 2;
	int32 batch_size = 3;
	int32 batch_index = 4;
	int32 batch_id = 5;
}

I then found this tutorial on Google for protocol buffers, which instructed me to download the proto command which ultimately led me here to get the compiled version for MacOS.

I then ran the command and received a generated .java class file which has multiple places in it with these statements in it:

com.google.protobuf.GeneratedMessageV3.isStringEmpty

But 'isStringEmpty' seems to be a reference to something that does not exist...

From where I stand, the proto command that generates the .java class is the point where this is failing as it seems to be inserting code into the class that it generates that makes calls to another class that do not exist.

What I would like to know ... is how do I fix the class that it generated?

This is the dependency that I'm using in my project by the way:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.19.1</version>
</dependency>

Edit:

When I downloaded proto version 3.17.3 from here and re-generated the class from that same .proto file, the resulting class did not contain the call to isStringEmpty and caused no errors while still using dependency version 3.19.1.

Thanks for your hint. It really helped me solve my issue.
I also tried using 3.19.2 but it didn't solve this problem.

I did the following:

  1. Downloaded the proto version 3.17.3 and copied it over to /usr/local/bin/protoc-3.17.3
  2. Included this proto version on my plugin settings on pom.xml as follows:
 <plugin>
        <groupId>org.xolstice.maven.plugins</groupId>
        <artifactId>protobuf-maven-plugin</artifactId>
        <extensions>true</extensions>
        <version>${protobuf-plugin.version}</version>
        <configuration>
          <protocArtifact>
            com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
          </protocArtifact>
          <pluginId>grpc-java</pluginId>
          <pluginArtifact>
            io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
          </pluginArtifact>
          <protoSourceRoot>
            src/submodules/grpc/streamm
          </protoSourceRoot>
          <protocExecutable>
            /usr/local/bin/protoc-3.17.3
          </protocExecutable>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>compile-custom</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

Also since this is still happening, should this issue be reopened or a new issue? @elharo

@elharo
Copy link
Contributor

elharo commented Jan 6, 2022

I do not believe there is a bug here. This is caused by a mismatch between the protoc compiler version and the runtime version.

@rafaribe
Copy link

rafaribe commented Jan 6, 2022

<protocExecutable>
            /usr/local/bin/protoc-3.17.3
</protocExecutable>

Removing this line and adding the 3.17.3 version to the protobuf-java-util solves the issue, however it still doesn't work with any version newer than that.

I do not believe there is a bug here. This is caused by a mismatch between the protoc compiler version and the runtime version.

Can you please elaborate? How can I use version 3.19.2 then?

@ulvimardaliyev
Copy link

Grpc was upgraded to 1.44.0 version on 27 Jan 2022 : both grpc-stub and grpc-protobuf. I used 1.43.2 version of grpc and this version solved isStringEmpty error.

grpc-stub in maven repository

@lucas-g-simoes
Copy link

lucas-g-simoes commented Apr 6, 2022

Using Spring Boot Starter (https://github.com/yidongnan/grpc-spring-boot-starter) with Spring 2.6.4 I got the same problem, I solved it by fixing the following versions:

<protobuf.version>3.14.0</protobuf.version>
<protobuf-plugin.version>0.6.1</protobuf-plugin.version>
<grpc.version>1.35.0</grpc.version>

@whiskey21
Copy link

I got same problem and solved by fixing the following versions:

implementation 'net.devh:grpc-server-spring-boot-starter:2.13.1.RELEASE'
protobufVersion = '3.19.2' protobufPluginVersion = '0.8.18' grpcVersion = '1.43.2'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests