Closed Bug 203752 Opened 22 years ago Closed 22 years ago

NativeGlobal is not serializable when propagating exceptions

Categories

(Rhino Graveyard :: Core, defect)

defect
Not set
normal

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: bc1-bugzilla, Assigned: norrisboyd)

References

()

Details

Attachments

(4 files)

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705) Build Identifier: Rhino 1.5r5pre Posting this error since a quick search through Bugzilla using 'NativeGlobal' did not show up anything. When using client/server (RMI) with Rhino JavaScript, exceptions do not get propagated. JavaScriptException has a constructor that takes as a parameter any Object and in case it is a org.mozilla.javascript.NativeGlobal exception cannot be serialized (JVM tries to serialize the exception and, consiquentialy, it's field 'value', which is not serializable). I have quickhacked JavaScriptException to work correctly: public JavaScriptException(Object value) { super(ScriptRuntime.toString(value)); // bugfix to allow serialization of NativeGlobal if (value instanceof Wrapper) { value = ((Wrapper) value).unwrap(); } if (value instanceof NativeGlobal) { this.value = value.toString(); } else { if(value instanceof Throwable) { initCause((Throwable) value); } this.value = value; } } But this hack is quick and dirty and the right way to go would probably be to make NativeGlobal serializable. Reproducible: Always Steps to Reproduce: 1. Fire up your favorite application server. 2. Make a *bean, call in it JavaScript that throws a (wrapped) exception. 3. Call the *bean from your client. Actual Results: java.io.NotSerializableException: org.mozilla.javascript.NativeGlobal at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1054) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1302) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1302) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278) at org.mozilla.javascript.ScriptableObject.writeObject (ScriptableObject.java:1833) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at java.io.ObjectStreamClass.invokeWriteObject (ObjectStreamClass.java:795) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1294) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278) at org.mozilla.javascript.NativeJavaObject.writeExternal (NativeJavaObject.java:880) at java.io.ObjectOutputStream.writeExternalData (ObjectOutputStream.java:1265) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1243) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1302) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.defaultWriteObject (ObjectOutputStream.java:367) at java.lang.Throwable.writeObject(Throwable.java:648) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at java.io.ObjectStreamClass.invokeWriteObject (ObjectStreamClass.java:795) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1294) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.defaultWriteObject (ObjectOutputStream.java:367) at java.lang.Throwable.writeObject(Throwable.java:648) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at java.io.ObjectStreamClass.invokeWriteObject (ObjectStreamClass.java:795) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1294) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.defaultWriteObject (ObjectOutputStream.java:367) at java.lang.Throwable.writeObject(Throwable.java:648) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at java.io.ObjectStreamClass.invokeWriteObject (ObjectStreamClass.java:795) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1294) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.defaultWriteFields (ObjectOutputStream.java:1330) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1302) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278) at java.util.LinkedList.writeObject(LinkedList.java:681) at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at java.io.ObjectStreamClass.invokeWriteObject (ObjectStreamClass.java:795) at java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1294) at java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1245) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278) at java.rmi.MarshalledObject.<init>(MarshalledObject.java:92) at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke (JRMPInvoker.java:387) at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261) at sun.rmi.transport.Transport$1.run(Transport.java:148) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:144) at sun.rmi.transport.tcp.TCPTransport.handleMessages (TCPTransport.java:460) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run (TCPTransport.java:701) at java.lang.Thread.run(Thread.java:536) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer (StreamRemoteCall.java:247) at sun.rmi.transport.StreamRemoteCall.executeCall (StreamRemoteCall.java:223) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133) at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source) at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke (JRMPInvokerProxy.java:275) at org.jboss.invocation.InvokerInterceptor.invoke (InvokerInterceptor.java:108) at org.jboss.proxy.TransactionInterceptor.invoke (TransactionInterceptor.java:77) at org.jboss.proxy.SecurityInterceptor.invoke (SecurityInterceptor.java:80) at org.jboss.proxy.ejb.StatefulSessionInterceptor.invoke (StatefulSessionInterceptor.java:117) at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:76) at $Proxy43.readBuffer(Unknown Source) at com.parsek.shell.ShellObjectReader._readObject (ShellObjectReader.java:83) at com.parsek.shell.ShellObjectReader.readObject (ShellObjectReader.java:98) at com.parsek.FormTest.getForm(FormTest.java:43) at _cp2__jsp._jspService(/forms/cp2.jsp:54) at com.caucho.jsp.JavaPage.service(JavaPage.java:75) at com.caucho.jsp.Page.subservice(Page.java:506) at com.caucho.server.http.FilterChainPage.doFilter (FilterChainPage.java:182) at com.caucho.server.http.Invocation.service(Invocation.java:315) at com.caucho.server.http.CacheInvocation.service (CacheInvocation.java:135) at com.caucho.server.http.RunnerRequest.handleRequest (RunnerRequest.java:344) at com.caucho.server.http.RunnerRequest.handleConnection (RunnerRequest.java:274) at com.caucho.server.TcpConnection.run(TcpConnection.java:139) at java.lang.Thread.run(Thread.java:534) Expected Results: Exception while executing com.parsek.io.ApplicationIOException at com.parsek.io.BufferImpl.setThrowable(BufferImpl.java:286) at com.parsek.shell.impl.Process.closeJob(Process.java:190) at com.parsek.shell.impl.Process.run(Process.java:249) at com.parsek.cpii.services.PoolRunner$1.run(PoolRunner.java:58) Caused by: com.parsek.forms.WizardProcessingException: org.mozilla.javascript.JavaScriptException: com.parsek.forms.NotAValidTypeException: Type 'Kakšen e-amil naslov imaš?' is not recognized as a valid type by this wizard. at com.parsek.forms.impl.WizardImpl.<init>(WizardImpl.java:223) at com.parsek.cp2.iskernel.InsurletImpl.<init>(InsurletImpl.java:32) at com.parsek.cp2.iskernel.ISEngine.openSession(ISEngine.java:157) at com.parsek.shell.commands.wizard.WizardExe.process (WizardExe.java:319) at com.parsek.shell.AbstractExecutable.execute (AbstractExecutable.java:615) at com.parsek.shell.impl.Process.run(Process.java:220) ... 1 more Caused by: org.mozilla.javascript.JavaScriptException: com.parsek.forms.NotAValidTypeException: Type 'Kakšen e-amil naslov imaš?' is not recognized as a valid type by this wizard. at org.mozilla.javascript.JavaScriptException.wrapException (JavaScriptException.java:77) at org.mozilla.javascript.NativeJavaMethod.call (NativeJavaMethod.java:265) at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1200) at org.mozilla.javascript.gen.c1.call(183:28) at com.parsek.forms.impl.WizardImpl.<init>(WizardImpl.java:220) ... 6 more
CC self
In the patch beyond making NativeGlobal to implement Serilalizable I removed unused import statements as well.
Bojan, but how did you managed to pass NativeGlobal instance to JavaScriptException? It is not visible from scripts and it is public class only for implementation reasons.
Status: NEW → ASSIGNED
I have not passed it to the exception; it got passed by itself :-) Actually, what happened is that the (java)script was executing and an exception happened in a Java class that this script was calling. Now, when this exception got propagated to the client (in this case, from jBoss to Resin and to the HTML), I got a NotSerializableException.
Reply to the last comment: That makes sense since the exception contains the scope object which holds indirectly NativeGlobal instance. It also means that serialization does not use org.mozilla.javascript.serialize.ScriptableOutputStream and hence quite inefficient, but that is a different issue.
While you are messing arround with JavaScriptException, is it possible to add if(value instanceof Throwable) { initCause((Throwable) value); } I know it's a Java 1.4 feature and not directly connected to this bug and don't know what's the Rhino's policy of supported Java versions, but it in the end it could be done with method.invoke() or something similar. This would help debugging a lot.
Patches to invoke initCause via reflection are welcome.
Added invoking od initCause() by reflection. Haven't tested it thorougly yet, but it should work.
For the above chnages since they has nothing to do with this bug report, please file a separated bugzilla report and mark it as enhancement or for simple improvment like this you can either mail to me or Norris Boyd directly. And please add diffs in unified output format (diff -u) not the sources so it would be easier to see changes. And one more tip: please expand all tabs.
k
I committed the change to make NG serializable
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Provisionally marking Verified. Bojan, could you confirm that this has fixed the problem for you? If not, please reopen this bug; thanks -
Status: RESOLVED → VERIFIED
Here's the initCause change in better patch form
My take on the previous patch to address to use single "catch (Exception ex)" and simply ignore exceptions if they happen for the following reasons: 1. Many JVM outside Sun/IBM implementations can throw RuntimeExceptions when reflection fails which does not fit the official signature. 2. Using single "catch (Exception ex)" saves a lot of byte code and makes class loading faster. 3. If exception that is not suppose to happen still generated System.err/System.out may not work as well. In general it is rather bad idea to use System.err/System.out for logging on embedded JVMs and if one needs such logging, it is better to provide a separated API for that since not everybody works with JDK 1.4.
Targeting as resolved against 1.5R5
Target Milestone: --- → 1.5R5
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: