Problems using protobufs with java and scala - java

I have a file xxx.proto. I downloaded the protobuf compiler and installed it. Then I issued this command
protoc --java_out=./ xxx.proto
and it generated my xxx.java
Now I want to compile this file into a class file which I can use with Scala.
javac xxx.java
Which gives me this error
xxx.java:7: package com.google.protobuf does not exist
com.google.protobuf.ExtensionRegistry registry) {
^
xxx.java:12450: package com.google.protobuf.Descriptors does not exist
private static com.google.protobuf.Descriptors.Descriptor
^
xxx.java:12453: package com.google.protobuf.GeneratedMessage does not exist
com.google.protobuf.GeneratedMessage.FieldAccessorTable
...
...
...
100 errors
Now I guessed, it doesnt have the package.
So I copied the class files of package com.google.protobuf into the same folder where xxx.java exists. Note - I didnt compile this package. I downloaded the jar from another extension which had the jar files. So I extracted them. Now my current path where xxx.java resides has com/google/protobuf/ *.class of protobuf library.
I issued the javac command again.
This time I got a different set of errors -
xxx.java:10: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
^
xxx.java:215: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
^
xxx.java:608: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
^
xxx.java:1017: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
..... 100 errors
I even tried to compile the source files which came with google protobufs. The generated java classes are giving the same errors.
Any ideas what to do ??
Answer
Okay. Thanks everyone.
The main problem is that protocol buffers compiler package from google doesnt by default create the java library. I assumed that it does and installs it. It actually does if you are running Maven. But i didnt have maven
So i compiled the code in /java/src and used the jar.
^

When compiling, you need to have protobuf lib on your classpath. All those missing packages and classes are from protobuf lib.
Find protobuf jar and use
javac -cp path/to/protobuf.jar xxx.java

You may need to use version 2.4.1 (or 2.4+, at least) of the protobuf kit, including making sure that you update protoc (the protobuf compiler) and recompile your proto definition using the new protoc. (In other words, everything has to be the same version:
the protobuf-vn.n.n.jar file;
the protoc compiler; and
the output of compiling your .proto files with protoc.
One I got everything synched, I began to move forward with a Clojure project I'm looking at. You may be encountering the same version skew problem.

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
you can download protoc.exe (new release) from>>.
https://code.google.com/p/protobuf/downloads/detail?name=protoc-2.5.0-win32.zip&can=2&q=
in your *.proto file you correctly config
option java_package = "com.example.package";
option java_outer_classname = "class name";

One can install the protobuf jar file using the ubuntu a
apt-get install libprotobuf-java
This will copy the protobuf-java-2.4.1.jar under /usr/share/java/
Hope this helps

Related

Compilation error in compiling Protobufs in Java using SBT build tool

I am using the Play framework (which uses SBT build tool) with Java where I need to consume a Protobuf. So I have xxx.proto file. I got binary protoc compiler and added to class path. so I see -
protoc --version
libprotoc 3.1.0
I have compiled the xxx.proto file using -
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/xxx.proto so it has generated xxx.java file.
Now when I am compiling this xxx.java file ( the project using sbt build tool)
[error] /my_project/app/helpers/xxx.java:7: package com.google.protobuf does not exist
[error] com.google.protobuf.ExtensionRegistryLite
[error] /my_project/app/helpers/xxx.java:11: package com.google.protobuf does not exist
[error] com.google.protobuf.ExtensionRegistry
[error] /my_project/app/helpers/xxx.java:6182: package com.google.protobuf.Descriptors does not exist
[error] com.google.protobuf.Descriptors.Descriptor
[error] /my_project/app/helpers/xxx.java:6185: package com.google.protobuf.GeneratedMessageV3 does not exist
[error] com.google.protobuf.GeneratedMessageV3.FieldAccessorTable`
I see in my installed library - com.google.protobuf jar is there.
My xxx.proto looks following -
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: xxx.proto
public final class xxx {
private xxx() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
......
Is there anything I have missed while generating the xxx.java file?
How should I fix these compilation error?
You need to make sure that you're using the exact same versions of protoc and libprotobuf.jar. From what you wrote, it sounds like you're using protoc version 3.1.0 but libprotobuf 2.5.0. You need to use libprotobuf 3.1.0 instead, otherwise you will get compile errors like the ones you quote.
Re-stating Kenton's answer with some more instructions:
In Intellij, click on External Libraries and find the jar for protobuf.
Check the version of protoc:
If they don't match, (as shown above) then you will get the compilation errors.
I've seen similar issue with maven after changing some field type in my proto schema and then building without doing a clean first. However, doing a clean and build fixed it every time.

how to compile interdependent packages in Java? [duplicate]

This question already has an answer here:
setting the correct classpath for compiling and running Java packages? [duplicate]
(1 answer)
Closed 9 years ago.
I have two packages in my project folder:
src/main/java/com/scg/domain/* and src/main/java/com/scg/util/*. Both of them have classes that import others.
eg:
import com.scg.util.Address in one of the Class in src/main/java/com/scg/domain/
and import com.scg.domain.TimeCard in one of the Class in src/main/java/com/scg/util/.
Now I want to compile all the Java files in both packages.
To compile all the Java files in src/main/java/com/scg/util/
I tried this:
javac -cp src/main/java/com/scg/domain/*:src/main/java/com/scg/util/* src/main/java/com/scg/util/*
but it gave me 72 errors. I am pasting a sample of it:
src/main/java/com/scg/domain/ClientAccount.java:11: error: cannot find symbol
public final class ClientAccount implements Account {
^
symbol: class Account
src/main/java/com/scg/domain/ConsultantTime.java:16: error: cannot find symbol
private Account account;
^
symbol: class Account
location: class ConsultantTime
src/main/java/com/scg/domain/ConsultantTime.java:35: error: cannot find symbol
public ConsultantTime(final Date date, final Account account,
^
symbol: class Account
location: class ConsultantTime
src/main/java/com/scg/domain/ConsultantTime.java:66: error: cannot find symbol
public Account getAccount() {
what is the easiest way to compile all the java files in two packages where there is dependency (I mean import here).
You should compile all the Java source files at once:
javac src/main/java/com/scg/domain/*.java src/main/java/com/scg/util/*.java
Your classpath option is useless, and not valid. The classpath is supposed to contain directories or jar files containing the root of a package tree, containing already compiled classes used by the source files you want to compile.
Compiling many files from the command line is useful to understand the mechanisms of the compilation. But you should really learn to use a build tool like Gradle or Ant to build your project, and an IDE to compile and test your classes during development.
EDIT:
Reading the documentation again, you can use -cp to specify path where sources must be found. But the root of the package tree must be specified:
-cp src/main/java

Getting compile error: package com.twilio.sdk does not exist

New-bee in java here.
I'm on an ubuntu 12.04 machine.
I am trying the Twilio API using java to make voice calls from an uiautomator test case and following the instructions provided at https://www.twilio.com/docs/java/install. I downloaded both twilio-java-sdk-3.4.2-with-dependencies.jar and twilio-java-sdk-3.4.2.jar from http://search.maven.org/#browse|1260284827 (pre-built).
I am using Twilio API in an uiautomator java project. I am able to build and run that uiautomator java project without implementing the Twilio API code. But if I try to use the Twilio API library, I get a compile time errors that it could not find the package.
Steps I'm doing:
1-> Open the java project in eclipse
2-> Add the Twilio java library twilio-java-sdk-3.4.2-with-dependencies.jar OR twilio-java-sdk-3.4.2.jar via BuildPath->Configure Build Path->Add External JARs.
I have following line of code to test if I can make the TwilioRestClient object. I have other test functions with the uiautomator and they work fine without this piece of code. Consider the following method in addition to other test methods.
test.java
//Assume all other required libraries are imported
import com.twilio.sdk.TwilioRestClient;
public class testClient extends UiAutomatorTestCase {
public void testMethodGetClient(){
try{
TwilioRestClient client = new TwilioRestClient("ACCOUNT_SID", "AUTH_TOKEN");
log.info("client: " + client.getAccountSid());
}catch(Exception e){
log.info(e.toString());
}
}
}
I do not get any reference errors in my code before the comiple/build command. To believe that, if I do client. ,eclipse shows me all the methods available for the client object. So, can I assume here that my import was successful?
Then I go the terminal and execute below command to create the build.xml file:
ubuntu terminal
$> android create uitest-project -n JARNAME -t 1 -p <PATH-TO-PROJECT>
$> ant clean build
Buildfile: <PATH-TO-PROJECT>/build.xml
-check-env:
[checkenv] Android SDK Tools Revision 22.3.0
[checkenv] Installed at <ANDROID-SDK-PATH>
-pre-clean:
clean:
[delete] Deleting directory <PATH-TO-PROJECT>/bin
-check-env:
[checkenv] Android SDK Tools Revision 22.3.0
[checkenv] Installed at <ANDROID-SDK-PATH>
-build-setup:
[getbuildtools] Using latest Build Tools: 19.0.0
[echo] Resolving Build Target for <PACKAGE-NAME>...
[getuitarget] Project Target: Android 4.2.2
[getuitarget] API level: 17
[echo] ----------
[echo] Creating output directories if needed...
[mkdir] Created dir: <PATH-TO-PROJECT>/bin
[mkdir] Created dir: /<PATH-TO-PROJECT>/bin/classes
-pre-compile:
compile:
[javac] Compiling 33 source files to <PATH-TO-PROJECT>/bin/classes
[javac] <PATH-TO-PROJECT>/test.java:15: package com.twilio.sdk does not exist
[javac] import com.twilio.sdk.TwilioRestClient;
[javac] ^
[javac] <PATH-TO-PROJECT>/test.java:42: cannot find symbol
[javac] symbol : class TwilioRestClient
[javac] location: class <packagename>.Telephony
[javac] TwilioRestClient client = new TwilioRestClient("ACCOUNT_SID", "AUTH_TOKEN");
[javac] ^
[javac] <PATH-TO-PROJECT>/test.java:42: cannot find symbol
[javac] symbol : class TwilioRestClient
[javac] location: class <packagename>.Telephony
[javac] TwilioRestClient client = new TwilioRestClient("ACCOUNT_SID", "AUTH_TOKEN");
[javac] ^
[javac] 3 errors
BUILD FAILED
<ANDROID-SDK-PATH>/tools/ant/uibuild.xml:183: Compile failed; see the compiler error output for details.
Total time: 1 second
The above command would create the .jar if I did not have the testMethodGetClient method. So, I serached for the articals for package not found errors, but most of them suggesting to add the library either via 'Add External Jars' or 'provide the class path'. I tried both and I get the same error. So, I came here and posting it as a new question.
Any help is greatly appreciated.
Regards,
Rumit
The default location for third party jars is normally the libs folder at the base of your project, i.e. <PATH-TO-PROJECT>.
bgossit's answer did help me going to the right direction. However, that alone was not enough. So, answering my question by my self explaining a little extra step I had to do.
My first bottle neck is resolved, that is to compile the project successfully. However, I am still not able to run the project on an Android device. I am marking this comment as an answer as the question was for the complie error. I am puting a new question for the runtime error.
I found that the uiautomator's 'android create project' command creates a 'build.xml' which internally calls '<ANDROID_SDK>/sdk/tools/ant/uibuild.xml' to build the project and create the final jar. By default, the 'compile' target in this 'uibuild.xml' does not have a 'classpath' inlcuded for the jar. This seems to be the bug with Android as mentioned on couple of other StackOverflow questions/answers.
Solution that worked for me:
Create the 'libs' directory at the same level as your 'src' directory and put your external jars into 'libs' directory. Note: This is just a good practice. Ideally you can give any name to the 'libs' directory and put it wherever you want.
Add the 'classpath' attribute to the 'compile' target in <ANDROID_SDK>/sdk/tools/ant/uibuild.xml.
<classpath>
<fileset dir="${jar.libs.dir}" includes="*.jar" /> <!-- path to 'libs' -->
</classpath>
PLEASE NOTE: Although, above solution worked to compile and build my project, I'm still not able to run it on the Android device as the Android device would not have Twilio API jar. I am looking for the ways to build the final project jar with Twilio jar/classes. java.lang.ClassNotFoundException for package com.twilio.sdk
Regards,
Rumit

Javac can't find class that is in the same directory

I am trying to compile a Java file and I'm getting this error message:
$ javac -cp "bc-j-mapi-w-2.4.jar;apache-commons/*;json-org/*;lib/*" BrightcoveVideoQueryPOI.java
BrightcoveVideoQueryPOI.java:57: cannot find symbol
symbol : class BrightcoveAPI
location: class BrightcoveVideoQueryPOI
BrightcoveAPI brightcoveAPI = new BrightcoveAPI(BrightcoveAPI.PROD_READ_URL_TOKEN);
^
BrightcoveVideoQueryPOI.java:57: cannot find symbol
symbol : class BrightcoveAPI
location: class BrightcoveVideoQueryPOI
BrightcoveAPI brightcoveAPI = new BrightcoveAPI(BrightcoveAPI.PROD_READ_URL_TOKEN);
^
BrightcoveVideoQueryPOI.java:57: cannot find symbol
symbol : variable BrightcoveAPI
location: class BrightcoveVideoQueryPOI
BrightcoveAPI brightcoveAPI = new BrightcoveAPI(BrightcoveAPI.PROD_READ_URL_TOKEN);
^
3 errors
This would suggest that javac cannot find the class BrightcoveAPI. I'm not sure what the problem is as it is in the same directory:
$ ls
apache-commons bc-j-mapi-w-2.4.jar BrightcoveAPI.class BrightcoveAPI.java BrightcoveVideoQueryPOI.java json-org lib
You need to include . (the current directory) in your classpath:
javac -cp ".;bc-j-mapi-w-2.4.jar;apache-commons/*;json-org/*;lib/*" BrightcoveVideoQueryPOI.java
Some notes:
. is in the default classpath, but if you use -cp to specify an explicit classpath, then it's only included if you specify it.
A previous version of this answer added . to the end of the classpath, but aioobe says that it's typically put first, which makes sense, so I've edited accordingly. (The classpath is searched in order, so if you have two copies of a class, one in . and one in a library, then you probably want the . version to supersede the library version, so you need to list it first. But of course, it's not usually a good thing to have two non-identical copies of a class!)
What you've pasted looks like a *nix shell, but you're using ;, which is the separator expected on Windows. (On *nix the expected separator is :.) This may well be correct, e.g. if you're using Cygwin, but I thought I'd mention it just in case.
If you do not search your current directory (your class path doesn't) javac won't add that directory in for you as an additional default.
This behavior allows the javac compiler to be called consistently for a project (set of source code files) independent of the directory the user that invoked the compiler. If it were any other way, then you would have to ensure that you always compiled from the same working directory to get the same results.
---- edit after seeing comment in ruakh's excellent answer ----
The second issue you are seeing isn't related to the first. The "Could not find or load main class" is because you are invoking the java command with the source code file name not the class name which is defined in that source code file.
The java command runs classes, not source code files. This makes more sense when you remember that a single source code file could contain more than one class (even if they typically don't).

"Cannot find symbol" for my own class

I do not have a %CLASSPATH% set up. As I understand, this should not be a problem because Javac will assume a classpath of the current directory.
As you can see below, javac is unable to find my Case class even though it's in the same exact directory. Any thoughts on why this is happening? This code works fine when I use Eclipse.
C:\Documents and Settings\joep\My Documents\GCJ\src\codejam2011\Round0\D>dir /B
Case.class
Case.java
EntryPoint.java
C:\Documents and Settings\joep\My Documents\GCJ\src\codejam2011\Round0\D>javac EntryPoint.java
EntryPoint.java:16: cannot find symbol
symbol : class Case
location: class codejam2011.Round0.D.EntryPoint
ArrayList<Case> cases = new ArrayList<Case>();
^
EntryPoint.java:16: cannot find symbol
symbol : class Case
location: class codejam2011.Round0.D.EntryPoint
ArrayList<Case> cases = new ArrayList<Case>();
^
EntryPoint.java:24: cannot find symbol
symbol : class Case
location: class codejam2011.Round0.D.EntryPoint
cases.add(new Case(new Integer(count), line));
^
3 errors
C:\Documents and Settings\joep\My Documents\GCJ\src\codejam2011\Round0\D>
Update 1:
After trying to compile from my package root (src), I get a new error (even after deleting the Case.class file)
C:\Documents and Settings\joep\My Documents\GCJ\src>javac -cp . codejam2011/Round0/D/EntryPoint.java
codejam2011\Round0\D\EntryPoint.java:16: cannot access codejam2011.Round0.D.Case
bad class file: .\codejam2011\Round0\D\Case.java
file does not contain class codejam2011.Round0.D.Case
Please remove or make sure it appears in the correct subdirectory of the classpath.
ArrayList<Case> cases = new ArrayList<Case>();
^
1 error
C:\Documents and Settings\joep\My Documents\GCJ\src>
Update 2:
It appears to be grabbing the Case.java file from a different package.
C:\Documents and Settings\joep\My Documents\GCJ\src>javac -d ../classes codejam2011\Round0\D\*.java
.\codejam2011\Round0\D\Case.java:4: duplicate class: codejam2011.Round0.C.Case
public class Case
^
codejam2011\Round0\D\EntryPoint.java:16: cannot access codejam2011.Round0.D.Case
bad class file: .\codejam2011\Round0\D\Case.java
file does not contain class codejam2011.Round0.D.Case
Please remove or make sure it appears in the correct subdirectory of the classpath.
ArrayList<Case> cases = new ArrayList<Case>();
^
2 errors
C:\Documents and Settings\joep\My Documents\GCJ\src>
You need to compile from the package root, not from inside the package.
So, cd to the src folder and compile from there.
javac -cp . codejam2011/Round0/D/EntryPoint.java
Update: as per your new problem, you need to recompile Case.java the same way. It was apparently compiled the same wrong way (from inside the package).
If the problem is not yet solved by compiling from the package root directory (see the other answers):
make sure all the source files contain classes with names corresponding to their file name
make sure all the source files contain a package statement corresponding to their position in the source file hierarchy
delete all your .class files before compiling (this should only be necessary once, if you checked everything else).
Thus, if the file is codejam2011\Round0\D\Case.java, it should contain package codejam2011.Round0.D; as the first declaration, and then public class Case { ... }. Also, make sure there is no other source file containing this package and class declaration.
From your error message, it looks like the package statement is package codejam2011.Round0.C; instead (and you also have a class Case in the real codejam2011.Round0.C package).
You are in the wrong directory for compiling.
location: class codejam2011.Round0.D.EntryPoint
That tells me, that your package is codejam2011.Round0.D (which is against the convention (all lowercase) but beside the point ...
cd to the parent dir of codejam2011, which is src, isn't it?
javac codejam2011\Round0\D\EntryPoint.java
might do the trick.
Often you have a directory for compiled classes, like 'bin' or 'classes'. To produce the classes there, use -d (destination):
javac -d ../classes codejam2011\Round0\D\EntryPoint.java
I have similar issue, it might not apply to all cases, but what I have done is remove .gradle, build and out folder and rebuild the program again.

Categories