From: <php...@li...> - 2011-01-26 15:10:05
|
Greetings everyone, I take part in a fairly big project, several different companies take part on it. The main platform is made in PHP, but usual corporative madness means that some parts of the project will be made in Java (looks like some companies would go bankrupt if they produce some PHP code :p). So far, we've been able to call java from our main php framework with php/java bridge, which seems to be fairly easy with php/java bridge. But in order to avoid duplicating some work, the java code should be able to call objects that exist in the main PHP, which are not able to do yet. We try this in the php file: require_once("http://localhost:8080/JavaBridge/java/Java.inc"); class FooPHPClass { function greet() { return "I'm a FooPHPClass function"; } } java_context()->setAttribute('FooPHPClass', java_closure(new FooPHPClass()), 100); $hw = new java("helloworld"); java_call_with_continuation(); echo $hw->hello(); In the java side, we are trying this: public class helloworld { public String hello() { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine e = manager.getEngineByName("php-invocable"); String v = ""; try { Invocable i = (Invocable) e; // This needs to call the class defined in the original PHP thread Object FooPHPClass = e.getContext().getAttribute("FooPHPClass", 100); v = (String) i.invokeMethod(FooPHPClass, "greet", new Object[] { new String() }); e.eval((Reader) null); // release the continuation, flush output } catch (javax.script.ScriptException ex) { } catch (java.lang.NoSuchMethodException ex) { } return "Invoke result: " +v; } } With this, running the php file in apache, we get a Java exception with the message: "java.lang.IllegalStateException: PHP script did not pass its continuation to us!". I don't really know how to proceed to make it work, since I'm really new to the php/java bridge. |
From: <php...@li...> - 2011-01-26 22:37:12
|
Hi, interesting concept. But it doesn't work, because the jsr223 api doesn't know about the existing php continuation and creates a new one. Jsr223 is for java->php->java... calls. For php->java->php... calls use java_closure: function toString() { return "i am a php Object method called from java called from php.";} echo java_closure(); Please see java_closure API doc for details. Regards, Jost Bökemeier |
From: <php...@li...> - 2011-01-27 17:40:51
|
Hi Jost, Thank you for the answer. I managed to pass closures of objects created in the main php file to java as parameters of functions. But since we have a large amount off objects in our project, the ideal thing would be that the java code should be able to instantiate classes defined in php by itself. To do so, I created the following classes. In php: class PHPClassFactory { private static $_instance; public static function getInstance() { if (! isset(self::$_instance)) self::$_instance = new self(); return self::$_instance; } public static function getClosure() { return java_closure(self::getInstance()); } public static function instanciate($class, $params = null) { return java_closure( new $class() ); } } In java: public class PHPClassFactory { private static Proxy factory; private static PHPClassFactory instance; public static void setProxy(Proxy phpproxy) { factory = phpproxy; } public static PHPClassFactory getInstance() { if (instance == null) instance = new PHPClassFactory(); return instance; } public static Proxy instanciate(String clase) throws Throwable { return instanciate(clase, null); } public static Proxy instanciate(String clase, Object[] params) throws Throwable { PhpProcedure phpp = (PhpProcedure) Proxy.getInvocationHandler(factory); return (Proxy) phpp.invoke(factory, "instanciate", new Object[] { clase } ); } public static Object call(Proxy object, String method, Object[] params) throws Throwable { PhpProcedure phpp = (PhpProcedure) Proxy.getInvocationHandler(object); return (Proxy) phpp.invoke(object, method, params); } } So any java code (called from the main php) should be able to instantiate a php class and use its methods like this: PHPClassFactory.setProxy(factory); Proxy foo = PHPClassFactory.instanciate("FooPHPClass"); return (String) PHPClassFactory.call(foo, "greet", null); However, it doesn't work. Running that gives a warning and a fatal error (which probably is because the previous warning): Warning: Missing argument 1 for java_InternalJava::java_InternalJava() and Fatal error: Uncaught [[o:Exception]:"java.lang.Exception: Invoke failed: [[o:helloworld]]->useGreetTwo((o:Proxy)[o:$Proxy0]). Cause: java.lang.NoSuchMethodError: greet I'm out of ideas right now. Can you give me a clue, please? Thank you again, Jaume Lopez El 26/01/2011 22:25, php...@li... escribió: > Hi, > > interesting concept. But it doesn't work, because the jsr223 api doesn't > know about the existing php continuation and creates a new one. > > Jsr223 is for java->php->java... calls. For php->java->php... calls use > java_closure: > > function toString() { return "i am a php Object method called from java > called from php.";} > > echo java_closure(); > > Please see java_closure API doc for details. > > Regards, > Jost Bökemeier > ------------------------------------------------------------------------------ > Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! > Finally, a world-class log management solution at an even better price-free! > Download using promo code Free_Logger_4_Dev2Dev. Offer expires > February 28th, so secure your free ArcSight Logger TODAY! > http://p.sf.net/sfu/arcsight-sfd2d > _______________________________________________ > php-java-bridge-users mailing list > php...@li... > https://lists.sourceforge.net/lists/listinfo/php-java-bridge-users |
From: <php...@li...> - 2011-01-27 20:18:43
|
Hi, your new $class() is wrong. $class is a JavaObject and new $JavaObject() requires at least one argument. Furthermore I'd use interfaces rather than the invocation handler: public class Test { public static interface PhpObjectFactory { PhpObject makeObject(String t, Object[] args); } public static interface PhpObject { void doSomething(Object[] args); int getResult(); } public static int runTests(PhpObjectFactory factory) throws Exception { PhpObject[] objects = new PhpObject[100]; for(int i=0; i<4; i++) { objects[i] = factory.makeObject("ClassTest"+i, new Object[]{i}); } for (int i=0; i<4; i++) { objects[i].doSomething(new Object[]{i}); } int res=0; for (int i=0; i<4; i++) { res+=objects[i].getResult(); } return res; } } <?php require_once("http://localhost:8080/JavaBridge/java/JavaBridge.inc"); class ClassTest0 { var $i; function ClassTest0 ($ar) { $this->i = $ar[0]; } function doSomething($ar) { $this->i += java_values($ar[0]); } function getResult() { echo "result:{$this->i}\n"; return $this->i; } } class ClassTest1 extends ClassTest0{}; class ClassTest2 extends ClassTest1{}; class ClassTest3 extends ClassTest2{}; function makeObject($tObj, $arObj) { $name = java_values($tObj); $ar = java_values($arObj); $obj = new $name($ar); return java_closure($obj, null, java('Test$PhpObject')); } echo java("Test")->runTests(java_closure(null, null, java('Test$PhpObjectFactory'))); ?> javac Test.java jar cf Test.jar *.class java -Djava.ext.dirs=. -jar JavaBridge.jar php -n -dallow_url_include=On test.php => 12 Regards, Jost Bökemeier |
From: <php...@li...> - 2011-01-28 16:47:32
|
Hi again Jost, That seems to be the clue I was needing. Since we can have a very high number of classes, I thought about adding methods to a php factory class so we can call methods and read properties of any php class without having to create an interface for each one (we'll still create interfaces for the most important classes only). Here's our class: class PHPClassFactory { private static $_instance; public static function getInstance() { if (! self::$_instance) self::$_instance = new self(); return self::$_instance; } public static function getClosure() { return java_closure( PHPClassFactory::getInstance(), null, java('Testing$PhpFactory')); } public function makeObject($tObj, $arObj) { $name = java_values($tObj); $ar = java_values($arObj); $obj = new $name($ar); return java_closure($obj); } public function call($j_instance, $j_method, $j_params) { $instance = java_unwrap( $j_instance ); $method = java_values( $j_method ); $params = array(); foreach ($j_params as $j_param) { $params[] = java_values($j_param); } $return = call_user_func_array(array($instance, $method), $params); $j_instance = java_closure($instance); if (is_object($valor)) { return java_closure($return); } else { return $return; } } public function set($j_instance, $j_property, $j_val) { $instance = java_unwrap( $j_instance ); $property = java_values( $j_property ); $instance->$property = java_values( $j_val ); $j_instance = java_closure($instance); } public function get($j_instance, $j_property) { $instance = java_unwrap( $j_instance ); $property = java_values( $j_property ); $valor = $instance->$property; if (is_object($valor)) { return java_closure($valor); } else { return $valor; } } } So, in java we can use code like this: public static interface PhpFactory { Object makeObject(String clase, Object[] params); Object call(Object inst, String method, Object[] params); Object set(Object inst, String method, Object value); Object get(Object inst, String property); } // ... Object record = factory.makeObject("rhcmsTestTable", new Object[] {}); factory.set(record, "name", "Alfalfa"); factory.call(record, "save", new Object[] {}); // Would be equivalent to: // $record = new rhcmsTestTable(); // $record->name = "Alfalfa"; // $record->save(); So far, all the test we have done (not a lot yet, tho) this code works as expected. What do you think about this approach? El 27/01/2011 21:18, php...@li... escribió: > Hi, > > your > > new $class() > > is wrong. $class is a JavaObject and new $JavaObject() requires at least > one argument. > > Furthermore I'd use interfaces rather than the invocation handler: > public class Test { > public static interface PhpObjectFactory { > PhpObject makeObject(String t, Object[] args); > } > public static interface PhpObject { > void doSomething(Object[] args); > int getResult(); > } > > public static int runTests(PhpObjectFactory factory) throws Exception { > PhpObject[] objects = new PhpObject[100]; > for(int i=0; i<4; i++) { > objects[i] = factory.makeObject("ClassTest"+i, new Object[]{i}); > } > > for (int i=0; i<4; i++) { > objects[i].doSomething(new Object[]{i}); > } > > int res=0; > for (int i=0; i<4; i++) { > res+=objects[i].getResult(); > } > return res; > } > } > > <?php require_once("http://localhost:8080/JavaBridge/java/JavaBridge.inc"); > > class ClassTest0 { > var $i; > function ClassTest0 ($ar) { > $this->i = $ar[0]; > } > function doSomething($ar) { > $this->i += java_values($ar[0]); > } > function getResult() { > echo "result:{$this->i}\n"; > return $this->i; > } > } > class ClassTest1 extends ClassTest0{}; > class ClassTest2 extends ClassTest1{}; > class ClassTest3 extends ClassTest2{}; > > function makeObject($tObj, $arObj) { > $name = java_values($tObj); > $ar = java_values($arObj); > $obj = new $name($ar); > return java_closure($obj, null, java('Test$PhpObject')); > } > > echo java("Test")->runTests(java_closure(null, null, > java('Test$PhpObjectFactory'))); > ?> > > javac Test.java > jar cf Test.jar *.class > java -Djava.ext.dirs=. -jar JavaBridge.jar > > php -n -dallow_url_include=On test.php > > => 12 > > > Regards, > Jost Bökemeier > ------------------------------------------------------------------------------ > Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! > Finally, a world-class log management solution at an even better price-free! > Download using promo code Free_Logger_4_Dev2Dev. Offer expires > February 28th, so secure your free ArcSight Logger TODAY! > http://p.sf.net/sfu/arcsight-sfd2d > _______________________________________________ > php-java-bridge-users mailing list > php...@li... > https://lists.sourceforge.net/lists/listinfo/php-java-bridge-users -- *Jaume López * Área de Innovación jau...@la... <mailto:jau...@la...> http://www.lavinia.tc/logos/lavinia_logo.gif www.laviniainteractiva.com <http://www.laviniainteractiva.com/> www.vertice360.com <http://www.vertice360.com/> T(34) 93 972 34 10 - ext 226 http://www.lavinia.tc/logos/vertice.jpg |