|
From: <php...@li...> - 2008-09-26 15:43:26
|
Hi,
For example:
>
> jrunscript -classpath JavaBridge.jar -l php-interactive
> > function toString() {return "hello Java, I am PHP";}
> > echo java_closure();
> => hello Java, I am PHP
>
> [to run the above example make sure that JavaBridge.jar and php-script.jar
> is in the current working directory and that jre/lib/ext does not contain
> JavaBridge.jar and php-script.jar -- Java doesn't have a module system,
> please
> see our README section Java Platform Issues for details. Use .NET or Mono
> if you
> don't like how Java works around that problem... ]
>
Removed the files from the jre/lib/ext directory. Ran the script. I get the
prompt. I enter the first line and hit enter. Result is a stack overflow
error traced back to line 89 of the InteractivePhpScriptEngine.java file (in
which the entered script is trimmed and a ';' is added as far as I can tell
by checking the source code):
Exception in thread "main" java.lang.StackOverflowError
at java.lang.String.<init>(String.java:216)
at java.lang.StringBuffer.toString(StringBuffer.java:585)
at
php.java.script.InteractivePhpScriptEngine.eval(InteractivePhpScriptEngine.java:89)
at
javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
at
php.java.script.InvocablePhpScriptEngine.invoke(InvocablePhpScriptEngine.java:97)
at
php.java.script.InvocablePhpScriptEngine.invokeFunction(InvocablePhpScriptEngine.java:108)
at
php.java.script.InteractivePhpScriptEngine.eval(InteractivePhpScriptEngine.java:91)
at
javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
at
php.java.script.InvocablePhpScriptEngine.invoke(InvocablePhpScriptEngine.java:97)
at
php.java.script.InvocablePhpScriptEngine.invokeFunction(InvocablePhpScriptEngine.java:108)
at
php.java.script.InteractivePhpScriptEngine.eval(InteractivePhpScriptEngine.java:91)
at
javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
(this goes on for a while)
Looking at the code what is happening (as far as I can see) is that it
attempts an eval call in InteractivePhpScriptEngine:
try {o=((Invocable)this).invokeFunction("javabridge_eval", new
Object[]{script});}catch(NoSuchMethodException ex){/*ignore*/};
For this it calls invokeFunction in InvocablePhpScriptEngine, which calls
invoke(String methodName, Object[] args) in InvocablePhpScriptEngine. This
method attempts if(scriptClosure==null) eval("<?php ?>") in line 97. This
eval call then leads to a repeat of the cycle until at some point it fails
at line 89 of the InteractivePhpScriptEngine with the stackoverlfowexception
since the stack is full. So somehow the evaluation of any input script fails
(including the "<?php ?>) until the stack is full. Any thoughts on what
might be causing this?
===================================================================================================
I also tried your example via Netbeans by adding the jar files directly to
the project (not onto the overall classpath by putting them in the
jre/lib/ext directory).
Your example to which I added a few debug lines using System.out.println:
package test;
>
> import java.io.Reader;
> import java.io.StringReader;
>
> import javax.script.Invocable;
>
> import php.java.script.InvocablePhpScriptEngine;
>
> public class HelloWorld {
>
> public static void main(String[] args) {
>
> String l = "3";
> System.setProperty("php.java.bridge.default_log_level", l);
> System.setProperty("php.java.bridge.default_log_file", "");
> System.setProperty("php.java.bridge.php_exec", "php-cgi");
>
> try {
> InvocablePhpScriptEngine engine = new InvocablePhpScriptEngine();
> String s = "<?php echo 'HelloWorld!\n'; ?>";
> System.out.println("here");
> engine.eval(new StringReader(s));
> System.out.println("here2");
> String name = (String)
> ((Invocable)engine).invokeFunction("java_get_server_name", new Object[]{});
> System.out.println("PHP/Java communication port: " + name);
>
> engine.eval((Reader)null);
>
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
> }
>
> The result:
>
> PHP/Java communication port: 127.0.0.1:9267
> HelloWorld!
My result:
here
here2
java.lang.NullPointerException
at java.lang.reflect.Proxy.getInvocationHandler(Proxy.java:636)
at
php.java.script.InvocablePhpScriptEngine.invoke(InvocablePhpScriptEngine.java:116)
at
php.java.script.InvocablePhpScriptEngine.invoke(InvocablePhpScriptEngine.java:100)
at
php.java.script.InvocablePhpScriptEngine.invokeFunction(InvocablePhpScriptEngine.java:108)
Here it seems the actual invoke is never reached in method invoke(Object
thiz, String methodName, Object[] args) as it fails while obtaining the
invocation handler through the Proxy class; and thus before calling the
invoke method on the phpscriptprocedure object. My best guess would be that
the 'thiz' object is null and this is why the proxy part fails.
InvokeFunction calls invoke(String methodName, Object[] args), which
contains the part
if(scriptClosure==null) eval("<?php ?>");
try {
return invoke(scriptClosure, methodName, args);
}
This call then invokes invoke(Object thiz, String methodName, Object[]
args), which leads to the null pointer exception at line 116. As you said
already, clearly also here the eval part either fails and returns null (just
like with the jrunscript test I did), or it is never performed.
The question is why. Any thoughts on why this is the case?
Kind regards,
Bart
p.s: thanks a lot for all your patience and efforts to help with this.
|