|
From: <php...@li...> - 2009-01-07 16:10:18
|
This is a follow up to the post: Configure bridge as a PHP Apache module or deploy into J2EE server? Thanks for the reply. I still require a little more advice if thats OK? Why do I definitely need Tomcat? Is the reason for this so that I can use JDBC -- can you explain why I need Tomcat? I have had a go at setting up the bridge myself and managed to do the following, which may or may not be correct: 1) I auto-deployed the JavaBridge.war in the tomcats webapps folder. 2) I then accessed www.mydomain.com/JavaBridge/index.php (remember that I am using mod_jk so this is accessing Tomcat's webapps folder) and ran the examples - but these scripts gave errors: Hello example gave this error Hello: function bindtextdomain not found. Please install language support, see http://php.net for details JSR 223 example2 gave this error: protocol error: Method Not Allowed The requested method PUT is not allowed for the URL /JavaBridge/jsp+php.jsp._cache_.phpjavabridge. , Internal error at col 4. Check the back end log for OutOfMemoryErrors. protocol error: Method Not Allowed The requested method PUT is not allowed for the URL /JavaBridge/jsp+php.jsp._cache_.phpjavabridge. , Internal error at col 4. Check the back end log for OutOfMemoryErrors. JSR 223 and IIS/Apache interaction example gave this error: protocol error: Method Not Allowed The requested method PUT is not allowed for the URL /JavaBridge/jsp+php2.jsp._cache_.phpjavabridge. , Internal error at col 4. Check the back end log for OutOfMemoryErrors. Could not evaluate script on IIS/Apache port 80: java.lang.IllegalArgumentException: reader must be a ScriptFileReader Are the above errors pointing to problems with my PHP-Java Bridge installation? If so, how can I go about fixing them? 3) Next I copied the JavaBridge folder to the Apache htdocs folder, and renamed it to JavaBridge2. 4) I then accessed the examples using www.mydomain.com/JavaBridge2/index.php - which points to my Apache htdocs folder. 5) Again, the same scripts gave the same errors as they did when accessing the scripts through Tomcat. 6) Next I compiled my own HelloWorld.java Java example. I did this by running the following command on the HelloWorld.java file.: - javac HelloWorld.java 7) Next I compiled the jar file using this command: - jar cvf HelloWorld.jar HelloWorld.class 8) I then created the helloworld.php file <?php require_once("java/Java.inc"); java_require('http://localhost/HelloWorld.jar'); $myObj = new Java('HelloWorld'); // display Hello World echo (String) $myObj->getHelloWorld(); ?> 9) Next I copied the HelloWorld.java, HelloWorld.class, HelloWorld.jar and helloworld.php files into the webapps/JavaBridge folder on Tomcat, and also to the htdocs/JavaBridge2 folder on Apache. When viewing the following URL's I saw the "Hello World" text in the browser, indicating that it had worked: www.mydomain.com/JavaBridge/helloworld.php www.mydomain.com/JavaBridge2/helloworld.php So does the above indicate that the PHP-Java Bridge is working as it should?? My example works fine when using PHP as an Apache module, or as FastCGI. Which would you recommend using? Does the PHP-Java bridge work better with one rather than the other? The most important question is will the way in which I have setup the PHP-Java Bridge provide the correct foundation for my proposed system i.e. will it allow me to achieve the following: IDMS <-----> JDBC <-----> Java <-----> /BRIDGE/ <-----> PHP <-----> Web?? Sorry for the huge post, i'm still getting my head around the basics. Once again, any help will be fantastic. kind regards Jonathan > > > Message: 8 > Date: Wed, 7 Jan 2009 12:00:22 -0000 > From: php...@li... > Subject: [Php-java-bridge-users] Configure bridge as a PHP Apache > module or deploy into J2EE server? > To: <php...@li...> > Message-ID: <D9991C4FC6614709BF8700521BFCB9DC@JPILLING> > Content-Type: text/plain; charset="iso-8859-1" > > Hi there, > > I am configuring a Linux server that will be eventually used as a web server. I am new to Java so some things are not clear to me, so please excuse any incorrect statements that I make. > > The idea is to connect to our IDMS database via JDBC Type 4 drivers from within a Java environment (which is installed on the Linux server), and then collect the data using Java and/or PHP through the PHP-Java Bridge, and then display the data over the web using PHP. > > I have Apache 2 configured, PHP as an Apache module and also as FastCGI, Apache mod_fastcgi, Tomcat server and the Apache mod_jk connectors. > > We want Apache 2 to handle all web requests and so we are using the mod_jk connectors to do this. i.e. if we want to view a JSP page online we can access it through www.mydomain.com/test.jsp instead of www.mydomain.com:8080/test.jsp. > > Considering our desired setup, how should I use the PHP-Java Bridge? Should I use it as an Apache PHP module, or just deploy it to the J2EE Tomcat server? > > The reason that I installed Tomcat is because I assumed it will create the JDBC connection with our IDMS database and allow PHP and Java to work together. However, I think that this may be incorrect and that all I need is Apache, PHP as an Apache module, the Java environment (SDK 6) to create the JDBC connection, and the PHP-Java Bridge as a PHP module. If we are not serving JSP pages then I can't see any need for Tomcat? Can you confirm that what I suspect is somewhat correct? > > Please advise as I'm quite confused which method to use. Any help will be much appreciated. > > Kind regards > Jonathan > > This message has been scanned for viruses by MailControl - www.mailcontrol.com > > > ------------------------------ > > Message: 9 > Date: Wed, 7 Jan 2009 14:19:39 +0000 (GMT) > From: php...@li... > Subject: Re: [Php-java-bridge-users] Configure bridge as a PHP Apache > module or deploy into J2EE server? > To: php...@li... > Message-ID: <498...@we...> > Content-Type: text/plain; charset=iso-8859-1 > > Hi, > > whether or not you intent to use JSP, you'll need tomcat anyway; although you can start a Java daemon from PHP (see http://php-java-bridge.sourceforge.net/pjb/examples/source.php?source=startJava.php), tomcat is much easier to set up and to handle than some Java daemon started from PHP. > > > Regards, > Jost B?kemeier > > > > > > > > ------------------------------ > > ------------------------------------------------------------------------------ > Check out the new SourceForge.net Marketplace. > It is the best place to buy or sell services for > just about anything Open Source. > http://p.sf.net/sfu/Xq1LFB > > ------------------------------ > > _______________________________________________ > php-java-bridge-users mailing list > php...@li... > https://lists.sourceforge.net/lists/listinfo/php-java-bridge-users > > > End of php-java-bridge-users Digest, Vol 32, Issue 2 > **************************************************** |
|
From: <php...@li...> - 2009-01-08 08:33:36
|
Thank you once again. >> Both modes, running PHP within Apache/IIS front-end or within a J2EE server back-end are supported. Which installation instructions do I follow to run PHP in the J2EE backend? Can you provide me a link to the correct php-java bridge instructions that I need to follow? Kind regards Jonathan Hi, > Why do I definitely need Tomcat? you need a J2EE server or a servlet engine of your choice. You can write your own J2EE server or use the test "J2EE" server built into JavaBridge.jar and ship it as part of your product, but you're responsible for this. We guarantee that the PHP/Java Bridge application works correctly on any servlet engine or J2EE server inplementing the J2EE spec >= 1.3. > Hello: function bindtextdomain not found. Please install > language support, see http://php.net for details Please see the PHP documentation for details. > The requested method PUT is not allowed for the URL mod_jk disables PUT requests. Remove mod_jk. Nobody needs it, anyway. Use mod_proxy instead. Please see our FAQ ("j2ee cluster") for details. > Are the above errors pointing to problems with my PHP-Java > Bridge installation? If so, how can I go about fixing them? It's a misunderstanding. If you really need mod_jk for tomcat on port 8080, start another tomcat on port 8081 and deploy the bridge into this one. Or configure mod_jk to not disable PUT requests. [use PHP] > as an Apache module, or as FastCGI. Which would you > recommend using? Depends on your requirements. If you want to install a cluster, use mod_proxy/balancer within the apache front end and run PHP in the J2EE back end. [FastCGI vs Apache/PHP SAPI] > Does the PHP-Java bridge work better with > one rather than the other? The SAPI doesn't matter. > IDMS <-----> JDBC <-----> Java <-----> > /BRIDGE/ <-----> PHP <-----> Web?? Both modes, running PHP within Apache/IIS front-end or within a J2EE server back-end are supported. ----- Original Message ----- From: Jonathan Pilling To: php...@li... Sent: Wednesday, January 07, 2009 3:52 PM Subject: Re: Configure bridge as a PHP Apache module or deploy into J2EE server? This is a follow up to the post: Configure bridge as a PHP Apache module or deploy into J2EE server? Thanks for the reply. I still require a little more advice if thats OK? Why do I definitely need Tomcat? Is the reason for this so that I can use JDBC -- can you explain why I need Tomcat? I have had a go at setting up the bridge myself and managed to do the following, which may or may not be correct: 1) I auto-deployed the JavaBridge.war in the tomcats webapps folder. 2) I then accessed www.mydomain.com/JavaBridge/index.php (remember that I am using mod_jk so this is accessing Tomcat's webapps folder) and ran the examples - but these scripts gave errors: Hello example gave this error Hello: function bindtextdomain not found. Please install language support, see http://php.net for details JSR 223 example2 gave this error: protocol error: Method Not Allowed The requested method PUT is not allowed for the URL /JavaBridge/jsp+php.jsp._cache_.phpjavabridge. , Internal error at col 4. Check the back end log for OutOfMemoryErrors. protocol error: Method Not Allowed The requested method PUT is not allowed for the URL /JavaBridge/jsp+php.jsp._cache_.phpjavabridge. , Internal error at col 4. Check the back end log for OutOfMemoryErrors. JSR 223 and IIS/Apache interaction example gave this error: protocol error: Method Not Allowed The requested method PUT is not allowed for the URL /JavaBridge/jsp+php2.jsp._cache_.phpjavabridge. , Internal error at col 4. Check the back end log for OutOfMemoryErrors. Could not evaluate script on IIS/Apache port 80: java.lang.IllegalArgumentException: reader must be a ScriptFileReader Are the above errors pointing to problems with my PHP-Java Bridge installation? If so, how can I go about fixing them? 3) Next I copied the JavaBridge folder to the Apache htdocs folder, and renamed it to JavaBridge2. 4) I then accessed the examples using www.mydomain.com/JavaBridge2/index.php - which points to my Apache htdocs folder. 5) Again, the same scripts gave the same errors as they did when accessing the scripts through Tomcat. 6) Next I compiled my own HelloWorld.java Java example. I did this by running the following command on the HelloWorld.java file.: - javac HelloWorld.java 7) Next I compiled the jar file using this command: - jar cvf HelloWorld.jar HelloWorld.class 8) I then created the helloworld.php file <?php require_once("java/Java.inc"); java_require('http://localhost/HelloWorld.jar'); $myObj = new Java('HelloWorld'); // display Hello World echo (String) $myObj->getHelloWorld(); ?> 9) Next I copied the HelloWorld.java, HelloWorld.class, HelloWorld.jar and helloworld.php files into the webapps/JavaBridge folder on Tomcat, and also to the htdocs/JavaBridge2 folder on Apache. When viewing the following URL's I saw the "Hello World" text in the browser, indicating that it had worked: www.mydomain.com/JavaBridge/helloworld.php www.mydomain.com/JavaBridge2/helloworld.php So does the above indicate that the PHP-Java Bridge is working as it should?? My example works fine when using PHP as an Apache module, or as FastCGI. Which would you recommend using? Does the PHP-Java bridge work better with one rather than the other? The most important question is will the way in which I have setup the PHP-Java Bridge provide the correct foundation for my proposed system i.e. will it allow me to achieve the following: IDMS <-----> JDBC <-----> Java <-----> /BRIDGE/ <-----> PHP <-----> Web?? Sorry for the huge post, i'm still getting my head around the basics. Once again, any help will be fantastic. kind regards Jonathan > > > Message: 8 > Date: Wed, 7 Jan 2009 12:00:22 -0000 > From: php...@li... > Subject: [Php-java-bridge-users] Configure bridge as a PHP Apache > module or deploy into J2EE server? > To: <php...@li...> > Message-ID: <D9991C4FC6614709BF8700521BFCB9DC@JPILLING> > Content-Type: text/plain; charset="iso-8859-1" > > Hi there, > > I am configuring a Linux server that will be eventually used as a web server. I am new to Java so some things are not clear to me, so please excuse any incorrect statements that I make. > > The idea is to connect to our IDMS database via JDBC Type 4 drivers from within a Java environment (which is installed on the Linux server), and then collect the data using Java and/or PHP through the PHP-Java Bridge, and then display the data over the web using PHP. > > I have Apache 2 configured, PHP as an Apache module and also as FastCGI, Apache mod_fastcgi, Tomcat server and the Apache mod_jk connectors. > > We want Apache 2 to handle all web requests and so we are using the mod_jk connectors to do this. i.e. if we want to view a JSP page online we can access it through www.mydomain.com/test.jsp instead of www.mydomain.com:8080/test.jsp. > > Considering our desired setup, how should I use the PHP-Java Bridge? Should I use it as an Apache PHP module, or just deploy it to the J2EE Tomcat server? > > The reason that I installed Tomcat is because I assumed it will create the JDBC connection with our IDMS database and allow PHP and Java to work together. However, I think that this may be incorrect and that all I need is Apache, PHP as an Apache module, the Java environment (SDK 6) to create the JDBC connection, and the PHP-Java Bridge as a PHP module. If we are not serving JSP pages then I can't see any need for Tomcat? Can you confirm that what I suspect is somewhat correct? > > Please advise as I'm quite confused which method to use. Any help will be much appreciated. > > Kind regards > Jonathan > > This message has been scanned for viruses by MailControl - www.mailcontrol.com > > > ------------------------------ > > Message: 9 > Date: Wed, 7 Jan 2009 14:19:39 +0000 (GMT) > From: php...@li... > Subject: Re: [Php-java-bridge-users] Configure bridge as a PHP Apache > module or deploy into J2EE server? > To: php...@li... > Message-ID: <498...@we...> > Content-Type: text/plain; charset=iso-8859-1 > > Hi, > > whether or not you intent to use JSP, you'll need tomcat anyway; although you can start a Java daemon from PHP (see http://php-java-bridge.sourceforge.net/pjb/examples/source.php?source=startJava.php), tomcat is much easier to set up and to handle than some Java daemon started from PHP. > > > Regards, > Jost B?kemeier > > > > > > > > ------------------------------ > > ------------------------------------------------------------------------------ > Check out the new SourceForge.net Marketplace. > It is the best place to buy or sell services for > just about anything Open Source. > http://p.sf.net/sfu/Xq1LFB > > ------------------------------ > > _______________________________________________ > php-java-bridge-users mailing list > php...@li... > https://lists.sourceforge.net/lists/listinfo/php-java-bridge-users > > > End of php-java-bridge-users Digest, Vol 32, Issue 2 > **************************************************** |
|
From: <php...@li...> - 2009-01-08 14:24:38
|
Hi, > Which installation instructions do I follow to run PHP in > the J2EE backend? Can you provide me a link to the correct > php-java bridge instructions that I need to follow? => http://php-java-bridge.sourceforge.net/pjb/installation.php Regards, Jost Boekemeier |
|
From: <php...@li...> - 2009-01-11 12:25:38
|
Hi Jost,
thanks for your answer, but you don't seem to get what I wanted to do:
You are showing me how to call testA() on an already existing PHP
object.
But I wanted to invoke a method with its name given as a String, so:
not: A.testA(B)
but: A.invokeMethod("testA", B)
Therefore I do not see why the Java part would need to know about the
methods available on A.
The only thing it has to do is:
- find object A in PHP (formerly created with "java_closure( new A() )")
- find object B in PHP (formerly created with "java_closure( new B() )")
- tell object A to invoke a method (given as a generic String, here:
"testA") with object B as parameter.
If I look at the Javadoc of the Java script-api, it says:
/**
* Invokes a procedure on an object which already defined in the
* script using the array of objects as its arguments set.
*
* @param methodName name of the procedure to be invoked
* @param thiz object on which the procedure is called
* @param args arguments set for the procedure
* @return resultant object after the execution of the
* procedure
* @throws ScriptException if the invocation of the procedure
* fails
*/
public Object invokeMethod(Object thiz,String methodName,Object[] args)
throws
ScriptException, NoSuchMethodException;
=> That's exactly what I want to do, isn't it?
It does not say that I first have to use getInterface() in order to
proof whether "thiz" understands method "methodName".
It also doesn't say that the args are not allowed to be script proxies
as well.
So, do I still get something wrong here or is this just not supported by
the PHP-Java-bridge?
Regards Juergen
|
|
From: <php...@li...> - 2009-01-11 15:07:37
|
Hi,
> But I wanted to invoke a method with its name given as a
> String
Well, use the Java reflection API.
Another possibility is to re-use the PHP/Java Bridge PhpProcedure:
cca.invokeA(ccb);
is equivalent to:
((PhpProcedure)Proxy.getInvocationHandler($cca))).invoke($cca, "invokeA", new Object[]{ccb});
Note the ccb, it has been resolved using the interface IB. If you want to invoke it dynamically, too, use the same procedure as above.
This part of the PHP/Java Bridge API and implementation won't change in the future, so you may use the above code within your application.
A complete example:
package test;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.OutputStreamWriter;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class TestGetInterface {
/**
* @param args
*/
public static void main(String[] args) throws Throwable {
//System.setProperty("php.java.bridge.default_log_file", "");
//System.setProperty("php.java.bridge.default_log_level", "3");
new TestGetInterface().doWork();
}
private ScriptEngine scriptEngine;
String classA = "class A{function toString(){return '::A';} function invokeA($b){$b->invokeB();}}\n";
String classB = "class B{function toString(){return '::B';} function invokeB(){echo '::B';}}\n";
String test = "<?php "+classA+classB+" $thiz=java_context()->getAttribute('thiz');\n$thiz->call(java_closure(new A()), java_closure(new B())); ?>";
private void doWork() throws Throwable {
scriptEngine = new ScriptEngineManager().getEngineByName("php-invocable");
scriptEngine.put("thiz", this);
ByteArrayOutputStream out;
OutputStreamWriter writer;
scriptEngine.getContext().setWriter(writer = new OutputStreamWriter(out = new ByteArrayOutputStream()));
scriptEngine.eval(test);
((Closeable)scriptEngine).close();
writer.close();
if(!"::B".equals(out.toString())) {
System.err.println("test failed");
System.exit(1);
}
System.out.println("test okay");
System.exit(0);
}
interface IA { public void invokeA(IB ccb); };
interface IB { public void invokeB(); };
public void call(Object $cca, Object $ccb) throws Throwable {
IA cca = (IA) ((Invocable)scriptEngine).getInterface($cca, IA.class);
IB ccb = (IB) ((Invocable)scriptEngine).getInterface($ccb, IB.class);
//cca.invokeA(ccb);
((php.java.bridge.PhpProcedure)java.lang.reflect.Proxy.getInvocationHandler($cca)).invoke($cca, "invokeA", new Object[]{ccb});
}
}
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-11 19:34:03
|
Hi Jost,
o.k., we're coming closer:
Your proposal is about the same I had already described in the attached file of my very first email.
I've now aligned it with your example.
-----------------------------------------------------------
Java looks like:
package php.java.bridge;
import java.lang.reflect.Proxy;
import php.java.bridge.Request.AbortException;
public class Test2 {
public void call(Object $cca, Object $ccb) {
PhpProcedure cca = (PhpProcedure)Proxy.getInvocationHandler($cca);
PhpProcedure ccb = (PhpProcedure)Proxy.getInvocationHandler($ccb);
try {
cca.invoke( $cca, "invokeA", new Object[]{ ccb } );
} catch (AbortException ae) {
} catch (Throwable e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
final String[] initArgs = {"LOCAL", "6", "javabridge_simple_callback.log"};
try {
(new Standalone()).init(initArgs);
} catch (Throwable t) {
t.printStackTrace();
System.exit(9);
}
}
}
-----------------------------------------------------------
PHP looks about this:
class a {
function invokeA($b) {
echo $b->invokeB();
}
}
class b {
function invokeB() {
echo "class b";
}
}
$c = new Java("php.java.bridge.Test2");
$a = java_closure(new a());
$b = java_closure(new b());
$c->call($a, $b)
-----------------------------------------------------------
If I run this then the log-file shows:
1. new Java("php.java.bridge.Test2"):
--> <C v="php.java.bridge.Test2" p="I" ></C>
<-- <O v="1" m="php.java.bridge.Test2" p="O" n="T"/>
=> $c has Java-ID="1"
2. java_closure(new a()):
--> <I v="0" m="makeClosure" p="I" />
--> <L v="2513895" p="O" />
--> </I>
<-- <O v="2" m="php.java.bridge.PhpProcedureProxy" p="O" n="T"/>
=> $a has Java-ID="2"
3. java_closure(new b()):
--> <I v="0" m="makeClosure" p="I" />
--> <L v="2513278" p="O" />
--> </I>
<-- <O v="3" m="php.java.bridge.PhpProcedureProxy" p="O" n="T"/>
=> $b has Java-ID="3"
4. call($a, $b):
--> <I v="1" m="call" p="I" />
--> <O v="2" />
--> <O v="3" />
--> </I>
=> calling the method with the correct IDs ("2" and "3")
5. invokeA():
<-- <A v="2513895" p="aW52b2tlQSgp" m="aW52b2tlQSgp" n="1"><P><O v="4" m="php.java.bridge.PhpProcedure" p="O" n="T"/></P></A>
=> ID now passed back is "4" instead of "3"!
So, the PhpProcedure passed to invokeA() is a new one.
(which in turn causes invokeB() to fail...)
Did I find a bug here?
Regards Jürgen
|
|
From: <php...@li...> - 2009-01-12 13:37:53
|
Hi Juergen,
> public void call(Object $cca, Object $ccb) {
> cca.invoke( $cca, "invokeA", new Object[]{ ccb
> So, the PhpProcedure passed to invokeA() is a new one.
yes, obviously. ccb != $ccb. However, why is this a problem?
> (which in turn causes invokeB() to fail...)
> Did I find a bug here?
What do you mean with causes invokeB() to fail? The test case I've attached in my previous mail runs correctly, invokeB() correctly returned the string ::B, so I don't see the problem.
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-12 14:21:18
|
Hello!
=> ID now passed back is "4" instead of "3"!
Object #4 is the invocation handler, object #3 a Proxy. You have passed back the invocation handler instead of the proxy, see here:
PhpProcedure ccb = (PhpProcedure)Proxy.getInvocationHandler($ccb);
try {
cca.invoke( $cca, "invokeA", new Object[]{ ccb } );
} catch (AbortException ae) {
Peter
|
|
From: <php...@li...> - 2009-01-17 10:11:21
|
Hi Jost,
in one of your previous responses you wrote:
> cca.invokeA(ccb);
> is equivalent to:
> ((PhpProcedure)Proxy.getInvocationHandler($cca))).invoke($cca, "invokeA", new Object[]{ccb});
> Note the ccb, it has been resolved using the interface IB.
> If you want to invoke it dynamically, too, use the same procedure as above.
So, because of your last statement I passed ccb instead of $ccb.
If I pass $ccb, however, I also get a new object to PHP (again v="4" instead of v="3") which is the $Proxy0 now,
and this one does also not understand method invokeB() (resulting in a java.lang.NoSuchMethodException).
So, what did you mean with "use the same procedure as above"?
(I believe that if I'd resolve ccb using the interface IB - as you did in your example - then it might work.
But this is exactly what I want to avoid:
Java should be agnostic of whatever method I want to invoke in PHP.
The method name should just be passed onto Java and the method be invoked dynamically.
Otherwise I would always have to provide all these methods as Java interfaces before I could call them.
And this would shoot down all the dynamics of PHP here.)
But I think I start to understand where the general contradiction is,
so let me try to draw a sequence diagram in pseudo code in order to explain
what I believe you expect it to behave and what I actually expected.
You probably see it like this:
PHP Java
--------------------------------------------
0 (before here closures have been created already)
1 $c->call($a, $b)
2 call($cca, $ccb)
3 => cca = getInvocationHandler($cca)
4 => cca.invoke( $cca, "invokeA", $ccb )
5 $a.invokeA($b)
6 => $b.invokeB()
7 $ccb.invokeB()
8 $b.invokeB()
9 => echo '::B'
(and that is the same whether I replace $ccb by ccb or not)
Whereas what I'd expect is:
....
5 $a.invokeA($b)
6 => $b.invokeB() // no Java call here!
9 => echo '::B'
To put that into prosa:
I want $a to call invokeB() on $b WITHOUT going back to Java (that's why I expect v="3" to get passed to PHP).
But it seems to me that you expect that invokeB() is always invoked through Java.
Is this correct?
Is this by intention?
Is there any way for me to achieve what I want?
(Because when I know that invokeB() is just to be invoked on $b on the PHP-side why should I take the overhead of going back through Java again?)
Regards Jürgen
-----Ursprüngliche Nachricht-----
Von: php...@li... [mailto:php...@li...]
Gesendet: Montag, 12. Januar 2009 14:38
An: php...@li...
Betreff: Re: [Php-java-bridge-users] How to wrap two PHP objects as javaclosures,and in Java call a method on the first closure with the secondclosure as parameter?
Hi Juergen,
> public void call(Object $cca, Object $ccb) {
> cca.invoke( $cca, "invokeA", new Object[]{ ccb
> So, the PhpProcedure passed to invokeA() is a new one.
yes, obviously. ccb != $ccb. However, why is this a problem?
> (which in turn causes invokeB() to fail...) Did I find a bug here?
What do you mean with causes invokeB() to fail? The test case I've attached in my previous mail runs correctly, invokeB() correctly returned the string ::B, so I don't see the problem.
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-17 18:25:19
|
Hello!
If I pass $ccb, however, I also get a new object to PHP (again v="4"
$ccb is and has been your Proxy$0, so how can the same object have two object numbers? (note that you wrap your proxy, but the wrapped object is still the same).
So, what did you mean with "use the same procedure as above"?
I think he wants you to use the reflection API.
Peter
|
|
From: <php...@li...> - 2009-01-17 18:45:33
|
Hi,
> $ccb is and has been your Proxy$0, so how can the same
> object have two object numbers?
Not really. The return value of java_closure() is resolved lazily. A PhpProcedureProxy becomes an InvocationHandler + Proxy$xxx when a Java procedure or setter is called.
In other words Java always sees the Proxy$xx and the PhpProcedure associated with it.
> I think he wants you to use the reflection API.
Yes. You need to retrieve the InvocationHandler and call its method.
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-18 10:34:47
|
Hi Jost,
> "But I don't understand why you insist using your own test case..."
Sorry, that I didn't explain yet:
The actual reason is that my whole setup is different (which maybe of interest for as well):
I don't use a web environment at all.
I have my PHP script in a file and call PHP from the command line.
Java-Bridge is running standalone.
So, the initiator for all communication is PHP (and not Java using the script engine like you do).
It didn't work at the beginning, but after modyfing Java.inc (e.g. changing ports 8080 to 9267, creating SimpleHandler instead of HttpHandler) it worked.
At the beginning I thought that my code should be understandable/reproducable for you.
But after I realized that in order to do so, you have to modify Java.inc, it seems clear to me, that no one may have done it like this before.
Anyway, I understood something from your latest reply:
With "use the same procedure as above" you meant use it in PHP instead of Java, like this:
> String classA = "class A{function toString(){return '::A';} function invokeA($b){java('java.lang.reflect.Proxy')->getInvocationHandler($b)->invoke($b, "invokeB", array());}}\n";
(this wasn't the case in your first example)
I also think these two lines are not necessary anymore:
> interface IA { public void invokeA(IB ccb); };
> interface IB { public void invokeB(); };
My test case now works (also without the two lines above) - thanks so far.
But still my general question is not answered:
Why shouldn't it be possible to resolve the actual parameter $b to the actual PHP-object directly on the PHP-side without going back to Java?
I thought that if you call java_closure($b) and later a method gets invoked on $b then the bridge first resolves $b and the method gets invoked directly on the PHP-object $b.
Is there any way to avoid this round-trip?
Regards Jürgen
-----Ursprüngliche Nachricht-----
Von: php...@li... [mailto:php...@li...]
Gesendet: Samstag, 17. Januar 2009 19:45
An: php...@li...
Betreff: Re: [Php-java-bridge-users] How to wrap two PHP objects asjavaclosures,and in Java call a method on the first closure with the secondclosureas parameter?
Hi Juergen,
I really don't understand the problem. I have posted a test case which does what you want.
I do understand that you don't have the information to resolve the type, so that you must call the methods through the reflection API.
But I don't understand why you insist using your own test case, which cannot work, because you confuse the proxy with the invocation handler.
-------------------------------------
package test;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.OutputStreamWriter;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class TestGetInterface {
/**
* @param args
*/
public static void main(String[] args) throws Throwable {
//System.setProperty("php.java.bridge.default_log_file", "");
//System.setProperty("php.java.bridge.default_log_level", "3");
new TestGetInterface().doWork();
}
private ScriptEngine scriptEngine;
String classA = "class A{function toString(){return '::A';} function invokeA($b){java('java.lang.reflect.Proxy')->getInvocationHandler($b)->invoke($b, "invokeB", array());}}\n";
String classB = "class B{function toString(){return '::B';} function invokeB(){echo '::B';}}\n";
String test = "<?php "+classA+classB+" $thiz=java_context()->getAttribute('thiz');\n$thiz->call(java_closure(new A()), java_closure(new B())); ?>";
private void doWork() throws Throwable {
scriptEngine = new ScriptEngineManager().getEngineByName("php-invocable");
scriptEngine.put("thiz", this);
ByteArrayOutputStream out;
OutputStreamWriter writer;
scriptEngine.getContext().setWriter(writer = new OutputStreamWriter(out = new ByteArrayOutputStream()));
scriptEngine.eval(test);
((Closeable)scriptEngine).close();
writer.close();
if(!"::B".equals(out.toString())) {
System.err.println("test failed");
System.exit(1);
}
System.out.println("test okay");
System.exit(0);
}
interface IA { public void invokeA(IB ccb); };
interface IB { public void invokeB(); };
public void call(Object $cca, Object $ccb) throws Throwable {
((php.java.bridge.PhpProcedure)java.lang.reflect.Proxy.getInvocationHandler($cca)).invoke($cca, "invokeA", new Object[]{$ccb});
}
}
--------------
> So, what did you mean with "use the same procedure as above"?
Use the Java reflection API. The above example shows how to do this in PHP and in Java.
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-18 15:21:46
|
> Why shouldn't it be possible to resolve the actual
> parameter $b to the actual PHP-object directly on the
> PHP-side without going back to Java?
Do you want to resolve the parameter or the argument? I assume you want to unwrap the wrapped PHP object. It might be a good idea to extend java_values() this way.
However you can always access your PHP object through other mechanisms.
Regards,
Jost Bökemeier
|
|
From: <php...@li...> - 2009-01-20 22:40:46
|
Hi,
> assume you want to unwrap the wrapped PHP object. It might
> be a good idea to extend java_values() this way.
the change is in the cvs head now. The current download version 5.4.3.1 also contains this feature. From the NEWS:
Version 5.4.3.1
* java_unwrap($closure) can now used to retrieve the PHP object
associated with a java_closure(). Example:
class f{function __toString(){return "p";}function toString(){return "j"}};
$cl = java_closure(new f());
echo $cl;
=> j
$cl = java_unwrap($cl)
echo $cl;
=> p
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-26 07:39:44
|
Hi,
thanks a lot - this works now for me.
Remarks:
In a different answer you said to someone else:
"Until now this was only possible by asking the PHP object for its ID (through a Java method) and then fetching the object from a global array using the obtained ID as a key."
Isn't it correct to say:
"Before 5.4.3.1 this wasn't possible at all, but since 5.4.3.1 it is possible by asking the PHP object for its ID (through a Java method) and then fetching the object from a global array using the obtained ID as a key."?
Nevertheless this is still not exactly what I wanted/expected:
One still has to go back to Java once (using java_unwrap()) in order to retrieve the ID.
Even better would be an API in Java that would allow to directly send this ID.
I've seen the new methods JavaBridge.unwrapClosure() and PhpProcedure.unwrap().
I may try using these in order to make my solution even better...
Anyway, thanks a lot again for your time and help!
Regards Jürgen
-----Ursprüngliche Nachricht-----
Von: php...@li... [mailto:php...@li...]
Gesendet: Dienstag, 20. Januar 2009 23:14
An: php...@li...
Betreff: Re: [Php-java-bridge-users] How to wrap two PHP objectsasjavaclosures,and in Java call a method on the first closure with thesecondclosureas parameter?
Hi,
> assume you want to unwrap the wrapped PHP object. It might be a good
> idea to extend java_values() this way.
the change is in the cvs head now. The current download version 5.4.3.1 also contains this feature. From the NEWS:
Version 5.4.3.1
* java_unwrap($closure) can now used to retrieve the PHP object
associated with a java_closure(). Example:
class f{function __toString(){return "p";}function toString(){return "j"}};
$cl = java_closure(new f());
echo $cl;
=> j
$cl = java_unwrap($cl)
echo $cl;
=> p
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-18 18:38:54
|
Hi Jost, > Do you want to resolve the parameter or the argument? > I assume you want to unwrap the wrapped PHP object. > It might be a good idea to extend java_values() this way. I think in order to avoid confusion between "argument" and "parameter", I would say I want to "unwrap" the wrapped PHP object. But: invokeA() is called with a $Proxy0-object (ID v="4") How should java_values() be able to "unwrap" the proxy in order to get the actual PHP object which has been wrapped before using java_closure() resulting in an object with ID v="3"? It is not clear to me how this "ID-mapping" should work!? > However you can always access your PHP object through other mechanisms. Any hint how? What I already tried on the Java-side is to get a handle on the object that has been created with java_closure(). But I could not find out how to come from the $Proxy0-object to the PhpProcedure (which I assume is the one which has ID v="3" which I'm looking for). Other question regarding Java.inc: invokeBegin() is defined like this: function invokeBegin($object, $method) but called so: $client->protocol->invokeBegin(0, "makeClosure", "5", "6"); What's the meaning of "5" and "6" if invokeBegin() can only accept 2 parameters? Regards Jürgen -----Ursprüngliche Nachricht----- Von: php...@li... [mailto:php...@li...] Gesendet: Samstag, 18. Januar 2009 15:21 An: php...@li... Betreff: Re: [Php-java-bridge-users] How to wrap two PHP objects asjavaclosures,and in Java call a method on the first closure with the secondclosureas parameter? > Why shouldn't it be possible to resolve the actual > parameter $b to the actual PHP-object directly on the > PHP-side without going back to Java? Do you want to resolve the parameter or the argument? I assume you want to unwrap the wrapped PHP object. It might be a good idea to extend java_values() this way. However you can always access your PHP object through other mechanisms. Regards, Jost Bökemeier |
|
From: <php...@li...> - 2009-01-19 16:15:19
|
Hi,
> How should java_values() be able to "unwrap" the
> proxy
by fetching the PHP object.
> > However you can always access your PHP object through
> other mechanisms.
> Any hint how?
With a dictionary for example.
> What's the meaning of "5" and "6"
Two proposed predicates, see the PROTOCOL.TXT. However, these will probably never be implemented.
Regards,
Jost Bökemeier
|
|
From: <php...@li...> - 2009-01-19 19:12:56
|
Hello!
With a dictionary for example.
Isn't it possible to simply use $this when a method is invoked from Java?!?
Peter
|
|
From: <php...@li...> - 2009-01-20 22:44:29
|
Peter,
> Isn't it possible to simply use $this when a method is
> invoked from Java?!?
we were talking about an optimation which fetches the PHP object associated with a Java closure.
Until now this was only possible by asking the PHP object for its ID (through a Java method) and then fetching the object from a global array using the obtained ID as a key.
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-17 19:02:51
|
Hi Juergen,
I really don't understand the problem. I have posted a test case which does what you want.
I do understand that you don't have the information to resolve the type, so that you must call the methods through the reflection API.
But I don't understand why you insist using your own test case, which cannot work, because you confuse the proxy with the invocation handler.
-------------------------------------
package test;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.OutputStreamWriter;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class TestGetInterface {
/**
* @param args
*/
public static void main(String[] args) throws Throwable {
//System.setProperty("php.java.bridge.default_log_file", "");
//System.setProperty("php.java.bridge.default_log_level", "3");
new TestGetInterface().doWork();
}
private ScriptEngine scriptEngine;
String classA = "class A{function toString(){return '::A';} function invokeA($b){java('java.lang.reflect.Proxy')->getInvocationHandler($b)->invoke($b, "invokeB", array());}}\n";
String classB = "class B{function toString(){return '::B';} function invokeB(){echo '::B';}}\n";
String test = "<?php "+classA+classB+" $thiz=java_context()->getAttribute('thiz');\n$thiz->call(java_closure(new A()), java_closure(new B())); ?>";
private void doWork() throws Throwable {
scriptEngine = new ScriptEngineManager().getEngineByName("php-invocable");
scriptEngine.put("thiz", this);
ByteArrayOutputStream out;
OutputStreamWriter writer;
scriptEngine.getContext().setWriter(writer = new OutputStreamWriter(out = new ByteArrayOutputStream()));
scriptEngine.eval(test);
((Closeable)scriptEngine).close();
writer.close();
if(!"::B".equals(out.toString())) {
System.err.println("test failed");
System.exit(1);
}
System.out.println("test okay");
System.exit(0);
}
interface IA { public void invokeA(IB ccb); };
interface IB { public void invokeB(); };
public void call(Object $cca, Object $ccb) throws Throwable {
((php.java.bridge.PhpProcedure)java.lang.reflect.Proxy.getInvocationHandler($cca)).invoke($cca, "invokeA", new Object[]{$ccb});
}
}
--------------
> So, what did you mean with "use the same procedure as above"?
Use the Java reflection API. The above example shows how to do this in PHP and in Java.
Regards,
Jost Boekemeier
|
|
From: <php...@li...> - 2009-01-07 18:37:48
|
Hi, > Why do I definitely need Tomcat? you need a J2EE server or a servlet engine of your choice. You can write your own J2EE server or use the test "J2EE" server built into JavaBridge.jar and ship it as part of your product, but you're responsible for this. We guarantee that the PHP/Java Bridge application works correctly on any servlet engine or J2EE server inplementing the J2EE spec >= 1.3. > Hello: function bindtextdomain not found. Please install > language support, see http://php.net for details Please see the PHP documentation for details. > The requested method PUT is not allowed for the URL mod_jk disables PUT requests. Remove mod_jk. Nobody needs it, anyway. Use mod_proxy instead. Please see our FAQ ("j2ee cluster") for details. > Are the above errors pointing to problems with my PHP-Java > Bridge installation? If so, how can I go about fixing them? It's a misunderstanding. If you really need mod_jk for tomcat on port 8080, start another tomcat on port 8081 and deploy the bridge into this one. Or configure mod_jk to not disable PUT requests. [use PHP] > as an Apache module, or as FastCGI. Which would you > recommend using? Depends on your requirements. If you want to install a cluster, use mod_proxy/balancer within the apache front end and run PHP in the J2EE back end. [FastCGI vs Apache/PHP SAPI] > Does the PHP-Java bridge work better with > one rather than the other? The SAPI doesn't matter. > IDMS <-----> JDBC <-----> Java <-----> > /BRIDGE/ <-----> PHP <-----> Web?? Both modes, running PHP within Apache/IIS front-end or within a J2EE server back-end are supported. Regards, Jost Boekemeier |
|
From: <php...@li...> - 2009-01-11 15:12:46
|
Hi,
I have added a new FAQ entry for this:#
<h4>What does "The requested method PUT is not allowed ... at localhost Port 80" mean?</h4>
<p>It means that <code>request.getServerPort()</code> is lying. Port 80 is privileged and therefore cannot be the servlet engine's server port.</p>
<p>If you use the AJP connector, for example via <code>ProxyPassMatch ^(/.*\.jsp)$ ajp://127.0.0.1$1</code>, set the correct <code>proxyPort</code> in <code>tomcat/conf/server.xml</code>. Example:
</p><blockquote>
<code>
<!-- Define an AJP 1.3 Connector on port 8009 --><br>
- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /><br>
+ <Connector port="8009" protocol="AJP/1.3" proxyPort="8080" redirectPort="8443" /><br>
</code>
</blockquote>
Please see the <a href="http://127.0.0.1:8080/docs/config/ajp.html#Proxy%20Support">AJP documentation</a><a> for details.
Regards,
Jost Boekemeier
|