Closed
Bug 203752
Opened 22 years ago
Closed 22 years ago
NativeGlobal is not serializable when propagating exceptions
Categories
(Rhino Graveyard :: Core, defect)
Rhino Graveyard
Core
Tracking
(Not tracked)
VERIFIED
FIXED
1.5R5
People
(Reporter: bc1-bugzilla, Assigned: norrisboyd)
References
()
Details
Attachments
(4 files)
827 bytes,
patch
|
Details | Diff | Splinter Review | |
4.88 KB,
text/plain
|
Details | |
2.40 KB,
patch
|
Details | Diff | Splinter Review | |
2.92 KB,
patch
|
Details | Diff | Splinter Review |
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
Comment 1•22 years ago
|
||
CC self
Comment 2•22 years ago
|
||
In the patch beyond making NativeGlobal to implement Serilalizable I removed
unused import statements as well.
Comment 3•22 years ago
|
||
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.
Comment 5•22 years ago
|
||
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.
Comment 7•22 years ago
|
||
Patches to invoke initCause via reflection are welcome.
Added invoking od initCause() by reflection.
Haven't tested it thorougly yet, but it should work.
Comment 9•22 years ago
|
||
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.
Reporter | ||
Comment 10•22 years ago
|
||
k
Comment 11•22 years ago
|
||
I committed the change to make NG serializable
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Comment 12•22 years ago
|
||
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
Assignee | ||
Comment 13•22 years ago
|
||
Here's the initCause change in better patch form
Comment 14•22 years ago
|
||
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.
You need to log in
before you can comment on or make changes to this bug.
Description
•