Apache OpenOffice (AOO) Bugzilla – Issue 16264
java/C++ brigde crashes under certain circumstances
Last modified: 2004-04-08 20:50:59 UTC
Hi Stephan, I'll attch some sample code, which illustrates the problem. Extract the zipfile at the toplevel directory of an arbitrary source module. Switch into the test2 directory and type dmake. This builds a native server component (one may forgive me the rude nonsene implementation). Start the server with uno -ro uno_types.rdb -c foo -l cppobj.uno.so -u "uno:socket,host=0,port=2002;urp;test" (on windows, you need a different command line, here you should also copy the uno-executable to the current directory, otherwise you may get a different cppobj.dll ...) Build the Client.java file with javac directly (having the usual uno jars in classpath). Starting the java file should give you output like Client@... [Proxy:38932 .... false which is not correct. Passing the object with the base Type (uncomment the appropriate line in the java file succeeds). I noticed, that also the server executable crashes when you terminate the java process afterwards. I currently investigate this issue. Don't know yet, whether it is related or a separate issue (Maybe the problem lies in the C++ bridge as a whole, not sure yet, but you should have a look at the java part) I leave it up to you to set a target. Bye, Joerg
Created attachment 7283 [details] Bugdoc (see text for an explanation)
Same as internal bug #92174#. Dropping that one and keeping this.
That the client prints "false" (because the Java object returned from the remote bridge is not == the Java object passed into the remote bridge) is *not* a bug. There is no guarantee that different UNO interfaces (or even a single UNO interface, requested multiple times) of a single UNO object are represented by only one Java object. Jörg, was this a misunderstanding? (I had thought you had a test case that demonstrated a *crash* when an object passed into the remote bridge with a derived type was returned from the remote bridge with a base type.) That the C++ side of the bridge crashes upon termination of the Java client seems to be unrelated to the Java issue discussed above. This crash can even be reproduced if the Client.java is reduced to public class Client implements com.sun.star.container.XEnumeration { ... public static void main(String[] args) throws Exception { ... set.insert(new com.sun.star.uno.Any( new com.sun.star.uno.Type( "com.sun.star.container.XEnumeration", com.sun.star.uno.TypeClass.INTERFACE), new Client())); set.createEnumeration(); System.exit(0); } } Passing this bug on to KSO to fix the C++ crash (and changed this bug's title accordingly).
Hi, strongly disagreeing here. Actually, the real problem lies in the java bridge, the C++ bridge has only a robustness problem. When you actually switch on logging in the C++ bridge, and invoke the nextElement() call on the proxy, you'll realize, that the nextElement() call once goes to the C++ server and then back to java. This is AT LEAST a performance bug, as this call can be handled inprocess. Also semantically, this is a problem. One feature of every uno environment should be, that there is a way to retrieve the original object again. In C++, this is done via the XUnoTunnel interface. In the java environment, in my understanding, this was done by guaranteeing, that you always get the orignal object again, so that you e.g. can check with instanceof, whether this is one of the objects, that you created. Typically, you will now ask me, where this is written down :o), and I think, I can only answer 'nowhere', just in the mind of Markus Meyer, I think. But IMHO, this makes a lot sense. But the reason for the crash in C++ runtime is more serious. As you correctly said, the crash occurs even in the very simple case of mapping a java object to c++ and back again. When you let the same Java code run with OOo 1.0 runtime (you need to do a minor modification to the code therefor), you'll realize that the crash does not occur. The reason is, that the current java bridge implementation seems to send releases for every mapped object, even for objects, that are located in the same process as the java bridge. This is incompatible to the OOo1.0 implementation and to the current c++ implementation, that does not send releases in this case. This should definitly be fixed in the 1.1 source tree. For robustness, the C++ bridge can be improved in such a way, that it should ignore releases for objects, which where mapped from the remote counterpart. Hope, this helps Joerg
In the meantime, I identified the problem as follows. The URP specification requires that "[w]hen sending the tuple 〈o, t〉 [where o is a UNO object and t a UNO interface type implemented by o], the sending side increments its reference count for 〈o, t〉, unless it consideres as bridged in [i.e., originating at the other side of the URP bridge] any tuple 〈o, t′〉, where t′ is a subtype of t (including t itself)." (At least that's how I just updated the spec.) The C++ URP bridge adheres to this specification. One problem with the Java URP bridge was that it ignored the "unless ..." clause entirely, and thus always sent release messages. This has been fixed for OOo 1.1 RC (internal bug #110444#). The remaining problem with the Java URP bridge is that it implements the "unless ..." clause as "unless it considers as bridged in the tuple <o, t>." Thus, it does not handle correctly the case where an object o is first bridged from Java to C++ with type XDerived (<o,XDerived> gets refcount 1 at Java side, C++ side considers it bridged in), and then back from C++ to Java with type XBase (C++ side considers <o,XDerived> bridged in, so does not increment refcount for <o,XBase> upon sending it, but Java side thinks otherwise and sends back release message for <o,XBase> to C++ side). That problem has to be fixed with this task, targeted for OOo 2.0. Jörg, I am not convinced why "One feature of every uno environment should be, that there is a way to retrieve the original object again." is a feature worth having. But maybe we should move a discussion about that to dev@udk...
Making the quote from the last entry readable: "[w]hen sending the tuple <o, t> [where o is a UNO object and t a UNO interface type implemented by o], the sending side increments its reference count for <o, t>, unless it consideres as bridged in [i.e., originating at the other side of the URP bridge] any tuple <o, t'>, where t' is a subtype of t (including t itself)."
Fixed Java bridge to conform to (broken) URP specification. Affected files (CWS sb7): bridges/test/java_uno/acquire/TestAcquire.java 1.2.2.3 bridges/test/java_uno/acquire/makefile.mk 1.2.2.2 bridges/test/java_uno/acquire/readme.txt 1.1.2.2 bridges/test/java_uno/acquire/testacquire.cxx 1.2.2.2 jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java 1.2.18.3 jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java 1.30.2.3
Updated list of affected files: Affected files (CWS sb7): bridges/test/java_uno/acquire/TestAcquire.java 1.2.2.3 bridges/test/java_uno/acquire/makefile.mk 1.2.2.2 bridges/test/java_uno/acquire/readme.txt 1.1.2.2 bridges/test/java_uno/acquire/testacquire.cxx 1.2.2.2 jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java 1.2.18.3 jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java 1.30.2.5 jurt/com/sun/star/lib/uno/environments/java/java_environment.java 1.11.28.2 ridljar/com/sun/star/uno/Type.java 1.10.22.1 ridljar/test/com/sun/star/uno/Type_Test.java 1.2.16.1
Steffen, you can verify this fix with the steps described in Jörgs initial description. The client's output should be "true", and the server should not crash.
change to started
remove fixed
resolved fixed
checked on Windows and Solaris and works -> verified.
checked again, ok -> closed