Given the following service:
message Message {
string content = 1;
}
service EchoService {
rpc echo (Message) returns (Message) {
option (google.api.http) = { get: "/echo" };
}
}
I want to read the option from Java. My understand is the following code should work:
HttpRule rule = Message.getDescriptor()
.getOptions()
.getExtension(AnnotationsProto.http)
However this doesn't compile, complaining about typing issues where it cannot resolve the method.
I am trying to follow this: https://developers.google.com/protocol-buffers/docs/proto.html#customoptions
So the question is, how do I read the option from Java?
Well this is embarrassing, its actually a completely different type.
AnnotationsProto.http implements type with a generic of MethodOptions (https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/DescriptorProtos.MethodOptions.html)
Whereas Message.getDescriptor().getOptions().getExtensions() is expecting a parameter with a generic of MessageOptions (https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/DescriptorProtos.MessageOptions.html)
MethodOptions vs MessageOptions - perhaps I need to get down to specsavers...
The following groovy code will fetch the http annotation
import com.google.api.AnnotationsProto
def methodDescriptorSupplier = (ProtoMethodDescriptorSupplier) grpcMethodDescriptor.getSchemaDescriptor()
def extension = methodDescriptorSupplier.getMethodDescriptor().getOptions().getExtension(AnnotationsProto.http)
Related
I am using RxBinding for Android widgets. I would like to do the following: Observable<java.lang.Void> obs = RxView.clicks(button);
But I get a compile time error saying that the expected type is kotlin.Unit. RxView.clicks(button) returns an Observable<Unit>but I don't think that Java has a Unit datatype.
How do I get an Observable<Void> in Java?
You can live with Observable<Unit> in Java. kotlin.Unit is a class file available for java programs as soon as kotlin-stdlib-<some version>.jar is in your class path, and it is there already because it is required by RxBinding.
If, however, some other part of your program requires Observable<Void>, it can be obtained with:
Observable<Unit> ou = RxView.clicks(button);
Observable<Void> ov = ou.as(unit->null);
This seems to have been asked in several places and has been marked as "closed" and "off-topic". However, people seem to have this problem constantly
invoking a php method from java (closed)
Calling PHP from Java (closed)
How can I run PHP code within a Java application? (closed)
This answer in the last question partly answers this but does not clarify how to read the outputs.
I finally found the answer to the question:
How do I run a PHP program from within Java and obtain its output?
To give more context, someone has given me a PHP file containing code for some method foo that returns a string. How do we invoke this from JVM?
Searching on Google is not helpful as all articles I found don't explain how to call PHP from Java but rather Java from PHP.
The answer below explains how to do this using the PHP/Java bridge.
The answer is in Scala but would be easy to read for Java programmers.
Code created from this SO answer and this example:
package javaphp
import javax.script.ScriptEngineManager
import php.java.bridge._
import php.java.script._
import php.java.servlet._
object JVM{ // shared object for PHP/JVM communication
var out = ""
def put(s:String) = {
out = s
}
}
object Test extends App {
val engine = (new ScriptEngineManager).getEngineByExtension("php")
val oldCode = """
<?php
function foo() {
return 'hello';
// some code that returns string
}
?>
"""
val newCode = """
<?php
$ans = foo();
java('javaphp.JVM')->put($ans);
?>
"""+oldCode
// below evaluates and returns
JVM.out = "" //reset shared output
engine.eval(newCode)
println("output is : "+JVM.out) // prints hello
}
To run this file:
Install PHP, Scala and set path correctly. Then create a file php.scala with the above code. Then run:
scalac php.scala
and
scala javaphp.Test
I wrote the following MyPythonGateway.java so that I can call my custom java class from Python:
public class MyPythonGateway {
public String findMyNum(String input) {
return MyUtiltity.parse(input).getMyNum();
}
public static void main(String[] args) {
GatewayServer server = new GatewayServer(new MyPythonGateway());
server.start();
}
}
and here is how I used it in my Python code:
def main():
gateway = JavaGateway() # connect to the JVM
myObj = gateway.entry_point.findMyNum("1234 GOOD DAY")
print(myObj)
if __name__ == '__main__':
main()
Now I want to use MyPythonGateway.findMyNum() function from PySpark, not just a standalone python script. I did the following:
myNum = sparkcontext._jvm.myPackage.MyPythonGateway.findMyNum("1234 GOOD DAY")
print(myNum)
However, I got the following error:
... line 43, in main:
myNum = sparkcontext._jvm.myPackage.MyPythonGateway.findMyNum("1234 GOOD DAY")
File "/home/edamameQ/spark-1.5.2/python/lib/py4j-0.8.2.1-src.zip/py4j/java_gateway.py", line 726, in __getattr__
py4j.protocol.Py4JError: Trying to call a package.
So what did I miss here? I don't know if I should run a separate JavaApplication of MyPythonGateway to start a gateway server when using pyspark. Please advice. Thanks!
Below is exactly what I need:
input.map(f)
def f(row):
// call MyUtility.java
// x = MyUtility.parse(row).getMyNum()
// return x
What would be the best way to approach this? Thanks!
First of all the error you see usually means the class you're trying to use is not accessible. So most likely it is a CLASSPATH issue.
Regarding general idea there are two important issues:
you cannot access SparkContext inside an action or transformation so using PySpark gateway won't work (see How to use Java/Scala function from an action or a transformation? for some details)). If you want to use Py4J from the workers you'll have to start a separate gateways on each worker machine.
you really don't want to pass data between Python an JVM this way. Py4J is not designed for data intensive tasks.
In PySpark before start calling the method -
myNum = sparkcontext._jvm.myPackage.MyPythonGateway.findMyNum("1234 GOOD DAY")
you have to import MyPythonGateway java class as follows
java_import(sparkContext._jvm, "myPackage.MyPythonGateway")
myPythonGateway = spark.sparkContext._jvm.MyPythonGateway()
myPythonGateway.findMyNum("1234 GOOD DAY")
specify the jar containing myPackage.MyPythonGateway with --jars option in spark-submit
If input.map(f) has inputs as an RDD for example, this might work, since you can't access the JVM variable (attached to spark context) inside the executor for a map function of an RDD (and to my knowledge there is no equivalent for #transient lazy val in pyspark).
def pythonGatewayIterator(iterator):
results = []
jvm = py4j.java_gateway.JavaGateway().jvm
mygw = jvm.myPackage.MyPythonGateway()
for value in iterator:
results.append(mygw.findMyNum(value))
return results
inputs.mapPartitions(pythonGatewayIterator)
all you need to do is compile jar and add to pyspark classpath with --jars or --driver-class-path spark submit options. Then access class and method with below code-
sc._jvm.com.company.MyClass.func1()
where sc - spark context
Tested with Spark 2.3. Keep in mind, you can call JVM class method only from driver program and not executor.
I am working in android. For reading the file content, I am using the method
List<String> lines = Files.readAllLines(wiki_path);
But whem I am using this method I am getting this error:
The method readAllLines(Path) is undefined for the type MediaStore.Files.
Why can the compiler not find the method?
Path wiki_path = Paths.get("C:/tutorial/wiki", "wiki.txt");
try {
List<String> lines = Files.readAllLines(wiki_path);
for (String line : lines) {
if(url.contains(line))
{
other.put(TAG_Title, name);
other.put(TAG_URL, url);
otherList.add(other);
break;
}
}
}
The method you're trying to use is a member of java.nio.file.Files - but that class (and indeed that package) doesn't exist on Android. Even if the Java 7 version existed, you're trying to use a method introduced in Java 8. The Files class you've imported is android.provider.MediaStore.Files which is an entirely different class.
Even if it compiled, the path you're providing looks ever so much like a Windows path, which wouldn't work on an Android device...
Explanation
I'm working on a game in Java where I have scriptable objects (buttons, switches etc..) on the map. By scriptable I mean that the objects have events (onActivation, onPress, etc..) and a script file is needed to be attached to the object in order to do something when its activated or pressed.
So event handling is done via scripting. My idea is to have a Groovy Script object created in Java by GroovyScriptEngine.createScript method. Then I call Script.invokeMethod("onActivation", null) in java to run the script when onActivation occurs. This seems to work.
Problem
However I have problems in my groovy script file. Here is the file:
test.groovy
def someVariable = 'test';
def onActivation() {
println testMessage; // comes from bindings
println someVariable;
}
Here is my java code where the Script object is created:
GroovyScriptEngine engine = new GroovyScriptEngine("assets/Scripts/");
Binding bindings = new Binding();
bindings.setProperty("testMessage", "Hello Script World!");
Script script = engine.createScript("test.groovy", bindings);
Later in the java code, when handling the onActivation event, I invoke the onActivation function from the script:
public void onActivationHandler() {
script.invokeMethod("onActivation", null);
}
But my groovy script fails with this message:
Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
groovy.lang.MissingPropertyException: No such property: someVariable for class: test
If I remove the someVariable declaration and the line where I print it, my script works and prints the following message:
Hello Script World!
TL;DR
Why does my script fail? Why doesn't my function see the variable named someVariable?
Edit
The same thing happens when I try to use GroovyShell instead of GroovyScriptEngine.
Edit2
If I try to get the value of someVariable in Java code by calling script.getProperty("someVariable"), it throws an exception telling me that the variable does not exists.
org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack: No such property: someVariable for class: proof
All right, I found the answer here. My test.script should look like this:
import groovy.transform.Field
#Field String someVariable = 'test';
def onActivation() {
println testMessage; // comes from bindings
println someVariable;
}
The script actually becomes a class (even if it doesn't contain class declaration). I need to add the #Field annotation to make it 'global' for the functions declared.
It also solved the problem mentioned in EDIT2. The variable became available via the script.getProperty("someVariable") call in Java.