Closed Bug 166530 Opened 22 years ago Closed 22 years ago

ClassCostException in FunctionObject static initializer

Categories

(Rhino Graveyard :: Core, defect)

x86
Windows 2000
defect
Not set
normal

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: lkuoza, Assigned: norrisboyd)

Details

Attachments

(1 file, 1 obsolete file)

When I run unit tests that use rhino in JUnit GUI test tunner I receive the 
following exception:

java.lang.ExceptionInInitializerError: java.lang.ClassCostException: 
org.mozilla.javascript.optimizer.InvokerImpl
  at org.mozilla.javascript.javascript.FunctionObject.newInvokerMaster(Unknown 
Source)
  ...

When I run it in JUnit text test runner, it works OK.

I believe that it is because GUI JUnit uses its own class loader and Rhino uses 
its own.

The following test case might be used to reproduce bug:


package com.actimind.watf;

import junit.framework.*;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;

public class RhinoTest extends TestCase
{
    public RhinoTest( String s )
    {
        super( s );
    }

    public void testRhino()
    {
        Context context = Context.enter();
        try
        {
            Scriptable scope = context.initStandardObjects( null );
        }
        finally
        {
            context.exit();
        }
    }
}


Just run this in GUI JUnit test runner, and see what happens.

I use Rhino 1.5R3
Various parts of Rhino need to define classes based on generated code and for
that they use org.mozilla.classfile.DefiningClassLoader. Currently its
DefiningClassLoader.loadClass(String name, boolean resolve) method when
searches for a class not defined by the loader itself calls
Thread.getContextClassLoader() on the assumption that an application may call
Thread.setContextClassLoader() to alter class loader for a particular thread. 

By default Thread.getContextClassLoader() returns the system classes loader and
if Rhino classes are not loaded through it, then any reference to a Rhino class
from the generated byte code would either lead to ClassNotFoundException or if
a copy of Rhino is available on the system loader to ClassCastException later
as in JVM classes with the same name but different class loaders are treated as
different classes. The later case I believe is the reason for the reported
error.

To resolve the issue, the patch changes DefiningClassLoader.loadClass to look
for a class from the parent class loader, which points to the loader that loads
Rhino classes and this is what necessary in all cases involving
DefiningClassLoader usage.
I committed the above patch with few other changes to replace calls to
Thread.getContextClassLoader() by using a proper parent class loader for
generated code. This fixed I believe a similar problem reported by Mike Gillam
as he confirmed that after the changes the following is no longer an issue:

Mike Gillam <mgillam@attbi.com> wrote to netsacpe.public.mozilla.jseng:
...
I am using Rhino to script business objects implemented within an EJB
Session object.

Everything works fine until I redeploy the .EAR file.  After
redeployment, none of the methods I expose in the ScriptableObject
classes work.  I get a ClassCastException.
...

 org.mozilla.javascript.JavaScriptException:
java.lang.ClassCastException
 	at
org.mozilla.javascript.JavaScriptException.wrapException(JavaScriptException.java:69)
 	at org.mozilla.javascript.FunctionObject.call(FunctionObject.java:439)
 	at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1225)
 	at
org.mozilla.javascript.gen.c85.call(IDBE_Pricing_Policy::SIZE_CRUST::IDV_Pricing_Formula:2)
 	at com.moose.bos.BusinessRule.execute(BusinessRule.java:88)
 	at com.moose.erp.PricingPolicy.price(PricingPolicy.java:88)
 	at com.moose.erp.ItemHasPrice.price(ItemHasPrice.java:106)
 	at com.moose.erp.Attribute.price(Attribute.java:225)
 	at
com.moose.erp.ItemHasAttributes.describeConfiguration(ItemHasAttributes.java:186)
 	at com.moose.erp.Item.configure(Item.java:245)
 	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 com.moose.bos.BusinessObj.callCommand(BusinessObj.java:69)
 	at com.moose.bos.BusinessObj.process(BusinessObj.java:488)
 	at com.moose.bos.Entity.process(Entity.java:1507)
 	at com.moose.bos.BusinessObj.processMessage(BusinessObj.java:574)
 	at com.moose.bos.Server.processMessage(Server.java:973)
 	at com.moose.bos.Server.processExternalMessage(Server.java:865)
 	at com.moose.ejb.BOSSessionStatelessBean.process(BOSSessionStatelessBean.java:125)
 	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
org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:664)
 	at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:186)
 	at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:96)
 	at
org.jboss.ejb.plugins.AbstractTxInterceptorBMT.invokeNext(AbstractTxInterceptorBMT.java:144)
 	at org.jboss.ejb.plugins.TxInterceptorBMT.invoke(TxInterceptorBMT.java:62)
 	at
org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:77)
 	at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:129)
 	at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
 	at
org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:313)
 	at org.jboss.ejb.Container.invoke(Container.java:705)
 	at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:491)
 	at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:98)
 	at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:102)
 	at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:73)
 	at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:76)
 	at
org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:111)
 	at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:76)
 	at $Proxy29.process(Unknown Source)
 	at com.moose.servlet.BOSSrvlet.callBOS(BOSSrvlet.java:108)
 	at
com.moose.servlet.ConfiguratorServlet.buildConfigFrame(ConfiguratorServlet.java:269)
etc.....
Marking FIXED -
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Tentatively marking Verified; Leonid, can you confirm
that the bug is fixed with the latest Rhino source?

If not, you can reopen this bug; thanks -
Status: RESOLVED → VERIFIED
Targeting as resolved against 1.5R4
Target Milestone: --- → 1.5R4
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: