gRPC the protoc compiler creates not the expected - java

i start whith gRPC bulding an easy Java Chat Programm.
protc --version prints libprotoc 3.5.1
the -proto File:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "grpc";
// whihout this Option i get no service
option java_generic_services = true;
option java_outer_classname = "ChatProto";
option objc_class_prefix = "HLW";
package chat;
message ClientPost {
string name = 1;
string value = 2;
}
message ServerReply {
ClientPost back = 1;
}
// The service definition.
service Verbindung {
rpc ChatService (stream ClientPost) returns (stream ServerReply);
}
// file end
why i need to set the option java_generic_services ?
class ChatImpl extends grpc.Verbindung {
#Override
public void chatService(RpcController controller, ClientPost request, RpcCallback done) {
// why i get this kind of Service ?
}
}
//
2. why i get an other class name ? shut be VerbindungImplBase
expected Function
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { }
what must i do to get this kind of expected Service Function ?
may be an wrong protoc compiler / wrong Installation / missing Parts ?

You're likely not running the gRPC code generator. Without the full configuration of how you're running protoc I can't point out too much detail, but you are likely only generating the protobuf messages via java_generic_services=true.
You shouldn't need java_generic_services=true. Instead, you should generate the messages like you are now, but then also use the grpc-java plugin. There's documentation for when running protoc manually and our main documentation documents the preferred method, using Maven or Gradle plugins.

I have an open suse leap 42.2 System
this Version knows nothing about grpc - no Support from this side
i get the compiled protoc - it comes whithout the needed Java-gen Plugin
found https://github.com/grpc/grpc-java/blob/master/compiler/README.md
"Normally you don't need to compile the codegen by yourself, since pre-compiled binaries for common platforms are available on Maven Central."
i found only some exe files. - not useful
"Change to the compiler directory:"
i have no compiler dir. - still try to find out were i can get
NetBeans have only an Editor plugin for protofiles - so my IDE can't handel gRPC
maybe for other IDEs are the Maven Plugins for gRPC are helpful
i expected an full protoc Compiler with all needed plugins :-)
not an install the tool adventure.
a the Moment for me: gRPC - nice Idea , but i get an "install the gRPC" Adventure

Related

Getting a specific version of an image with Jib (Maven, Docker, testcontainers)

I'm trying to understand a comment that a colleague made. We're using testcontainers to create a fixture:
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
public class SalesforceFixture extends GenericContainer<SalesforceFixture> {
private static final String APPLICATION_NAME = "salesforce-emulator";
public SalesforceFixture() {
// super(ImageResolver.resolve(APPLICATION_NAME));
super(DockerImageName.parse("gcr.io/ad-selfserve/salesforce-emulator:latest"));
...
}
...
The commented code is what it used to be. The next line is my colleague's suggestion. And on that line he commented:
This is the part I don't know. The [ImageResolver] gets the specific version of the emulator, rather than the latest. You need a docker-info file for that though, which jib doesn't automatically generate (but I think it can).
This is what I know or have figured so far:
SalesforceFixture is a class that will be used by other projects to write tests. It spins up a container in Docker, running a service that emulates the real service's API. It's like a local version of the service that behaves enough like the real thing that if one writes code and tests using the fixture, it should work the same in production. (This is where my knowledge ends.)
I looked into ImageResolver—it seems to be a class we wrote that searches a filesystem for something:
public static String resolve(String applicationName, File... roots) {
Stream<File> searchPaths = Arrays.stream(roots).flatMap((value) -> {
return Stream.of(new File(value, "../" + applicationName), new File(value, applicationName));
});
Optional<File> buildFile = searchPaths.flatMap((searchFile) -> {
if (searchFile.exists()) {
File imageFile = new File(searchFile + File.separator + "/target/docker/image-name");
if (imageFile.exists()) {
return Stream.of(imageFile);
}
}
return Stream.empty();
}).findAny();
InputStream build = (InputStream)buildFile.map(ImageResolver::fileStream).orElseGet(() -> {
return searchClasspath(applicationName);
});
if (build != null) {
try {
return IOUtils.toString(build, Charset.defaultCharset()).trim();
} catch (IOException var6) {
throw new RuntimeException("An exception has occurred while reading build file", var6);
}
} else {
throw new RuntimeException("Could not resolve target image for application: " + applicationName);
}
}
But I'm confused. What filesystem? Like, what is the present working directory? My local computer, wherever I ran the Java program from? Or is this from within some container? (I don't think so.) Or maybe the directory structure inside a .jar file? Or somewhere in gcr.io?
What does he mean about a "specific version number" vs. "latest"? I mean, when I build this project, whatever it built is all I have. Isn't that equivalent to "latest"? In what case would an older version of an image be present? (That's what made me think of gcr.io.)
Or, does he mean, that in the project using this project's image, one will not be able to specify a version via Maven/pom.xml—it will always spin up the latest.
Sorry this is long, just trying to "show my work." Any hints welcome. I'll keep looking.
I can't comment on specifics of your own internal implementations, but ImageResolver seems to work on your local filesystem, e.g. it looks into your target/ directory and also touches the classpath. I can imagine this code was just written for resolving an actual image name (not an image), since it also returns a String.
Regarding latest, using a latest tag for a Docker image is generally considered an anti-pattern, so likely your colleague is commenting about this. Here is a random article from the web explaining some of the issues with latest tag:
https://vsupalov.com/docker-latest-tag/
Besides, I don't understand why you ask these questions which are very specific to your project here on SO rather than asking your colleague.

Jenkins: Is there any API to see test reports remotely?

I'm using jenkins as CI tool. I used restful api to build a job remotely but I don't know how to get test result remotely as well.
I can't be more thankful if anybody know a solution
Use the XML or Json API. At most pages on Jenkins you can add /api/ to the url and get data in xml, json and similar formats. So for a job you can go to <Jenkins URL>/job/<Job Name>/api/xml and get informaiton about the job, builds, etc. For a build you can go to <Jenkins URL>/job/<Job Name>/<build number>/api/xml and you will get a summary for the build. Note that you can use the latestXXXBuild in order to get the latest successful, stable, failing, complete build, like this; <Jenkins URL>/job/<Job Name>/lastCompletedBuild/api/xml.
Additionally if youre using any plugin which publishes test results to the build, then for a given job you can go to <Jenkins URL>/job/<Job Name>/lastCompletedBuild/testReport/api/xml and you will get an xml report with results.
There is a lot more to it, you can control what is exported with the tree parameter and depth parameter. For a summary go to <Jenkins URL>/api/
Well, if you are using a jenkins shared library or decided to permit the security exceptions (a less good approach) then you can access them via a job and send them out to whatever you like - push vs pull
def getCurrentBuildFailedTests() {
def failedTests = []
def build = currentBuild.build()
def action = build.getActions(hudson.tasks.junit.TestResultAction.class)
if (action) {
def failures = build.getAction(hudson.tasks.junit.TestResultAction.class).getFailedTests()
println "${failures.size()} Test Results Found"
for (def failure in failures) {
failedTests.add(['name': failure.name, 'url': failure.url, 'details': failure.errorDetails])
}
}
return failedTests
}

java.lang.IllegalAccessError using org.apache.commons.cli when calling CommandLineParser#parser

I'm trying to use the Apache Commons CLI library to parse command line options in an Eclipse project, roughly following the examples in their Usage Scenarios
I added the commons-cli-1.3.1 folder to the lib folder in the root of the Eclipse project.
I added this to my imports:
import org.apache.commons.cli.*;
And this to the top of my main:
Options options = new Options();
CommandLineParser parser = new DefaultParser();
CommandLine cmd = null;
try {
cmd = parser.parse( options, args);
} catch ( ParseException e1 ) {
System.err.println( "Unable to parse command-line options: "+e1.getMessage() );
e1.printStackTrace();
}
It compiles without error, but when it runs the parser.parse call generates this error:
Exception in thread "main" java.lang.IllegalAccessError: tried to access method org.apache.commons.cli.Options.getOptionGroups()Ljava/util/Collection; from class org.apache.commons.cli.DefaultParser
I am not using any class loaders at this point.
What does this error mean? How can I resolve the error and parse the arguments?
This is the most probably a dependency problem.
It happens when you compile your code agains one version of the library (1.3.1 in your case) and then run with the older version of this library in your classpath.
I came across exactly this problem today when I had dependecy on commons-cli-1.3.1, but I had commons-cli-1.2 in my classpath (because I used yarn jar to launch my application)
What you should do?
You can just try downgrading to 1.2 as suggested above (this helped me)
Review your classpath and search for another version of commons-cli
What does your exception message really mean?
It means that some code at runtime tries to call some method which it has no right to call. For example, this could be trying to call a private method. Usually this is caught during compilation.
But if, for example, your code tries to call some function which is public in 1.3.1, but was private in 1.2. And if you compiled agains 1.3.1 but trying to launch with 1.2 in the classpath you will get that kind of error.
Hope it is clear.
I am using the commons-cli to handle the command line parameters of my game OpenPatrician. Basically there are three parts to it. The definition of the allowed command line arguments:
Options opts = new Options();
opts.addOption(HELP_OPTION, "help", false, "Display help");
opts.addOption(OptionBuilder.withLongOpt(VERSION_OPTION)
.withDescription("Version of this application")
.create());
opts.addOption(FULLSCREEN_MODE, "fullscreen", false, "fullscreen mode");
opts.addOption(OptionBuilder.withArgName(WINDOWED_MODE)
.withLongOpt("windowed")
.hasOptionalArgs(1)
.withArgName("widthxheight")
.withDescription("Windowed mode with optional definition of window size like: 1280x780")
.create());
opts.addOption(GAME_LOCALE, "lang", true, "Specify the locale to use");
opts.addOption(CLIENT_OPTION, "client", false, "Start application in client mode. Currently unused. Either client or server must be specified");
opts.addOption(SERVER_OPTION, "server", false, "Start application in server mode. Currently unused. Either client or server must be specified");
Providing a help message with all the possible parameters:
public void printHelp(Options options) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "OpenPatrician", options );
}
And of course the parsing of the arguments:
public CommandLine parseCommandLine(Options options, String[] args) {
try {
// parse the command line arguments
CommandLineParser parser = new PosixParser();
return parser.parse( options, args );
}
catch( ParseException exp ) {
printHelp(options);
throw new IllegalArgumentException("Parsing of command line arguments failed", exp);
}
}
Note that I am using a PosixPaser here and not the default parser. So that might have different behaviour.

Android protobuf nano usage

I am trying to generate java files from below proto file using protobuf nano. I got some basic instruction on how to proceed in this SO thread.
I have this proto file, personal.proto:
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}
I tried to follow the instruction from here, more specifically NANO version:
Downloaded protobuf-2.5.0.zip and compiler protoc-2.5.0-win32.zip from here.
Unzipped protobuf-2.5.0.zip to a folder and in there in src subfolder I unzipped protoc.exe.
Changed to java folder and in there issued: mvn clean package -P nano. That command ran fine and in target folder I have protobuf-java-2.5.0.jar
From here I am not sure how to proceed since in the initial documentation I have this statement:
- Link with the generated jar file
<protobuf-root>java/target/protobuf-java-2.3.0-nano.jar.
I am not sure what that means, how to link? Is there some parameter for protoc.exe that specifies the jar file to use?
I tried to issue this command: protoc --javanano_out=enum_style=java --java_out=generated personal.proto
but I get this error: --javanano_out: protoc-gen-javanano: The system cannot find the file specified.
The question would be: what am I missing/doing wrong above? I am trying to generate java files from above proto file.
I think this protoc is not compiled with javanano support.
The pre-compiled windows version 2.5.0 does not include nano support, take a look at the source code, in the "src\google\protobuf\compiler" path, includes the java generator but not the javanano generator. The latest source code at google repositories includes javanano.
You can download the latest source code and try to compile it using MinGW and msys or CygWin, take a look at this post How to build google protocol buffers in Windows for mingw?
(I will post details for the building process later)
UPDATE:
The final command line after building protoc.exe
For one proto file
protoc --javanano_out=store_unknown_fields=true:target/generated-sources personal.proto, target/generated-sources
For multiple proto files
protoc --javanano_out=store_unknown_fields=true:target/generated-sources --proto_path=inputpath input/*.proto
EDIT Nano generator replaces enum members with public static final int fields. This is a problem if a class has an optional enum member because that member will be compiled to a primitive int value and will take the default value of zero, which will be the first element from enum. To distinguish the cases when an enum value was not set, one can take advantage of optional_field_style parameter that will generate java.lang.Integer instead of a primitive int. When the proto is parsed, the caller can check if the value is null before using the value. Null means the value was not set.
The above call script can become:
protoc --javanano_out=store_unknown_fields=true,optional_field_style=reftypes:target/generated-sources --proto_path=input input/*.proto

Alloy API resulting in java.lang.UnsatisfiedLinkError

I'm currently using the Alloy Analyzer API to build a program, and getting some peculiar behavior. Specifically, if I open a file and parse it (using CompUtil.parseEverything), then make a new Command and call TranslateAlloyToKodkod.execute_command on the parsed file and newly created command using MiniSat with UNSAT core, it runs fine. However, later in execution, my program parses a second input file (also using CompUtil.parseEverything), gets another world, makes a new command, and then I try to call TranslateAlloyToKodkod.execute_command again, it throws the following error:
ERROR: class edu.mit.csail.sdg.alloy4.ErrorFatal: The required JNI library cannot be found:
java.lang.UnsatisfiedLinkError: no minisatproverx5 in java.library.path
edu.mit.csail.sdg.alloy4compiler.translator.TranslateAlloyToKodkod.execute_command(TranslateAlloyToKodkod.java:390)
Does anyone have any idea why this is thrown the second time, but not the first?
To summarize, I have something similar to the following:
Module someWorld = CompUtil.parseEverything_fromFile(rep, null, "someFile.als");
//For the following, "sig" is a sig in someWorld.getAllReachableSigs();
Command command = sig.not();
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.MiniSatProverJNI;
A4Solution ans =
TranslateAlloyToKodkod.execute_command(rep, someWorld, command, options);
//No thrown error
Module someOtherWorld = CompUtil.parseEverything_fromFile(rep, null, "someOtherFile.als");
//For the following, "sig" is a sig in someOtherWorld.getAllReachableSigs();
Command commandTwo = sig.not();
A4Solution ansTwo =
TranslateAlloyToKodkod.execute_command(rep, someOtherWorld, commandTwo, options);
//Thrown error above. Why?
I tried to reproduce this behavior, but I couldn't. If I don't add MiniSat binaries to the LD_LIBRARY_PATH environment variable, I get the exception you mentioned the very first time I invoke execute_command. After configuring LD_LIBRARY_PATH, the exception doesn't happen.
To configure LD_LIBRARY_PATH:
(1) if using Eclipse, you can right-click on one of your source folders, choose Build Path -> Configure Build Path, then on the "Source" tab make sure that "Native library location" points to a folder in which MiniSat binaries reside.
(2) if running from the shell, just add the path to a folder with MiniSat binaries to LD_LIBRARY_PATH, e.g., something like export LD_LIBRARY_PATH=alloy/extra/x86-linux:$LD_LIBRARY_PATH.
Here is the exact code that I was running, and everything worked
public static void main(String[] args) throws Exception {
A4Reporter rep = new A4Reporter();
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.MiniSatProverJNI;
Module someWorld = CompUtil.parseEverything_fromFile(rep, null, "someFile.als");
Command command = someWorld.getAllCommands().get(0);
A4Solution ans = TranslateAlloyToKodkod.execute_command(rep, someWorld.getAllReachableSigs(), command, options);
System.out.println(ans);
Module someOtherWorld = CompUtil.parseEverything_fromFile(rep, null, "someOtherFile.als");
Command commandTwo = someOtherWorld.getAllCommands().get(0);
A4Solution ansTwo = TranslateAlloyToKodkod.execute_command(rep, someOtherWorld.getAllReachableSigs(), commandTwo, options);
System.out.println(ansTwo);
}
with "someFile.als" being
sig A {}
run { some A } for 4
and "someOtherFile.als"
sig A {}
run { no A } for 4
I use alloy4.2.jar as a library in my eclipse plugin project.
A4Reporter rep = new A4Reporter();
Module world = CompUtil.parseEverything_fromFile(rep, null, "civi.als");
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.SAT4J;
options.skolemDepth = 1;
When I use SAT4J, the default solver, the problem mentioned here will not show up. But another exception comes out. The reason is that my civi.als file need Integer model, which located in alloy4.2.jar under the folder /models/util/. But when I run the application, it tries to find the file util/Integer.als directly. That causes the exception. Is it possible to fix that problem?
Besides, I also tried to put the alloy4.2.jar in eclipse plugin project and run my application as an eclipse application (running my application as a plugin). With the default solver, the application has no problem at all. But when I switch to MiniSatProverJNI, the problem mentioned here comes out (I have set the alloy4.2.jar as classpath).

Categories

Resources