From: <php...@li...> - 2010-06-21 07:15:15
|
Hi, I have a Java servlet (myServlet) running on Tomcat (downloaded from Apache). I also have a PHP script (test.php) sitting in the same directory as the servlet. I want to call functions in the PHP script from the Java servlet. I have deployed the JavaBridge.war file, can hit and run the examples, so I'm guessing nothing is broken in so far as JavaBridge and Tomcat are concerned. >From the examples, to reference the PHP script I should use something like: ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName( "php-invocable" ); scriptEngine.eval( new URLReader( "http://localhost/test.php" ); This does not make sense to me as my PHP script is not browseable (I only have Tomcat running on port 8080). I'd prefer not to access my script via a new request to Tomcat. Isn't it possible to access the script directly via the filesystem? If I try to pass in a URL as a file rather than http, I get a class cast exception: java.lang.ClassCastException: sun.net.www.protocol.file.FileURLConnection cannot be cast to java.net.HttpURLConnection Thanks, Bernard. _________________________________________________________________ New, Used, Demo, Dealer or Private? Find it at CarPoint.com.au http://clk.atdmt.com/NMN/go/206222968/direct/01/ |
From: <php...@li...> - 2010-06-21 08:16:15
|
> From the examples, to reference the PHP script I should use something like:ScriptEngine > scriptEngine = new ScriptEngineManager().getEngineByName( "php-invocable" ); Not exactly. For a servlet environment it is: php.java.script.servlet.EngineFactory.getInvocablePhpScriptEngine() The difference is that the ScriptEngineManager has no information about the servlet environment, so you cannot use the servlet context from a script allocated from the ScriptEngineManager. The JSR 223 script spec isn't very well designed. Implementations have to use their own workarounds. To quote Per Bothner: "Embarrassingly, I was a not-very-active member of the JSR-223 expert group. It would have been better if we could have thought a little more about scripting staticly-typed languages, but we didn't have time", see http://per.bothner.com/blog/2009/JavaFX-scripting-changes/ > scriptEngine.eval( new URLReader( "http://localhost/test.php" ); > This does not make sense to me I wasn't part of the JSR 223 expert group, so I don't know why they require you to pass a specific Reader, instead of a file or URL/URI. The URLReader is an adapter, it packages up the URI location so that it can be passed through the JSR 223 API. > as my PHP script is not browseable The java_call_with_continuation() makes it invocable from the remote continuation. It calls java_context()->call(this), so that Java can call that.cont.call(this.cont). If you open a local script via: reader = new java.io.FileReader(FILE); eng.eval(reader); the implementation hides the above "magic". > I'd prefer not to access my script via a new request to Tomcat It doesn't open a URLConnection back to tomcat. PHP uses a persistent connection to a ContextRunner: Client requests JSP. JSP creates ScriptEngine. ScriptEngine opens URLConnection to Apache/PHP. PHP script calls java method java_context() which invokes the bridge machinery in the back end (a java thread is spawned) and ->call() transfers the control from the PHP- to the current Java continuation, which may call procedures from the PHP continuation or transfer control back. I fail to understand your difficulties. If you mean the FileReader utility from EngineFactory; it is there to allow you to create a "one shot" reader for a given reader without having to look at the file system. The PHP file is created with the .class file during JSP compilation, so that PHP can take advantage of its internal cache/compilation mechanism (PHP compiles to opcode and caches it). > If I try to pass in a URL as a file rather than http Why don't you simply use a FileReader? Regards, Jost Bökemeier |
From: <php...@li...> - 2010-06-21 13:22:06
|
Thanks for your help - lots of details and yet I'm still baffled :-( The examples on the JavaBridge site don't seem to cover (what I thought to be) the simple case of a servlet accessing/executing a PHP script. To clarify: Within my Java servlet, if I want to call a PHP script test.php (say in the same directory as the servlet or at the very least on the same box as the servlet) then I first need to acquire a PHP engine. Assuming I have JavaBridge also deployed to the same servlet container as my servlet then this ScriptEngine scriptEngine = EngineFactory.getInvocablePhpScriptEngine( this, getServletContext(), httpServletRequest, httpServletResponse, new URI( "http://127.0.0.1:8080/JavaBridge/java/JavaProxy.php" ) ); should give me the script engine? Or is this actually pointing to JavaProxy.php as my script that will be executed? How then do I use a FileReader to point to my test.php and then call a function (say f) within test.php? Thanks again, Bernard. _________________________________________________________________ New, Used, Demo, Dealer or Private? Find it at CarPoint.com.au http://clk.atdmt.com/NMN/go/206222968/direct/01/ |
From: <php...@li...> - 2010-06-22 07:43:32
|
Hi Bernard, now I understand the problem. You cannot acquire an invocable php script engine from the current servlet container. The only available script engine is the PhpScriptEngine, which you cannot cast to invocable. The invocable script engine can only call remote PHP script methods or procedures. The API has been removed in version 6 because I cannot think of a real-world scenario where it is necessary to instanciate a local PHP script and call some of its methods. You may as well use the non-invocable PHP script engine or simply use requestDispatcher.forward() or .include() > ScriptEngine scriptEngine = EngineFactory.getInvocablePhpScriptEngine( > this, getServletContext(), httpServletRequest, httpServletResponse, new URI( > "http://127.0.0.1:8080/JavaBridge/java/JavaProxy.php" ) ); > > should give me the script engine? Yes. But you should be careful to not exceed the servlet engine pool size. > How then do I use a FileReader to point to my test.php and then call a > function (say f) within test.php? Create a script: <?php include("app"); echo f(); ?> and use the EngineFactory.getPhpScriptEngine(..).eval(...) or use <jsp:include > to invoke it. Regards, Jost Bökemeier |
From: <php...@li...> - 2010-07-07 16:44:18
|
Hi, this has been fixed in version 6.2.1. The EngineFactory is gone. You can now run a standard script engine in a servlet environment by decorating the ScriptContext. Please see http://php-java-bridge.sourceforge.net/pjb/server/documentation/API/php/java/script/PhpSecureScriptContext.html for an example. A PhpServletDecorator should provide concrete implementations of getHttpServletRequest(), ..., to provide the values from the closed-over environment. Regards, Jost Bökemeier |
From: <php...@li...> - 2010-07-11 12:06:12
|
> A PhpServletDecorator should provide concrete implementations of > getHttpServletRequest(), ..., to provide the values from the > closed-over environment. There's a ready-made decorator in PHP/Java Bridge 6.2.1-test1: http://php-java-bridge.cvs.sourceforge.net/viewvc/php-java-bridge/php-java-bridge/server/php/java/script/servlet/PhpCompiledHttpScriptContext.java?revision=1.1&view=markup It can be used as follows: private static final CompiledScript script = ((Compilable)(new ScriptEngineManager().getEngineByName("php-invocable"))).compile("<?php echo java_context()->get('hello'); function f($p){return (string)$p+1;};?>"); ScriptContext ctx = new php.java.script.servlet.PhpCompiledHttpScriptContext(script.getEngine().getContext(),this,application,request,response); script.eval(ctx); out.println(String.valueOf(((Invocable)script.getEngine()).invokeFunction("f", new Object[]{1}))+"<br>"); ((Closeable)script.getEngine()).close(); Please see examples http://php-java-bridge.cvs.sourceforge.net/viewvc/php-java-bridge/php-java-bridge/examples/php%2Bjsp/jsr223.jsp?view=markup&sortby=date and http://php-java-bridge.cvs.sourceforge.net/viewvc/php-java-bridge/php-java-bridge/examples/php%2Bjsp/jsp%2Bphp.jsp?view=markup&sortby=date Regards, Jost Bökemeier |