Hi,

I'm not quite sure if I'm allowed to use dynamic proxies in my enterprise
beans. There is no explicit restriction in the EJB 1.1 spec but
section 18.1.2 says:

  "The enterprise bean must not attempt to create a class loader; obtain the
   current class loader; set the context class loader; set security manager;
   create a new security manager; stop the JVM; or change the input, output,
   and error streams."

http://java.sun.com/j2ee/blueprints/ejb_tier/qanda/restrictions.html
is less rigid:

  "Specifically, enterprise beans should not: 
   ...
   create or modify class loaders and security managers"

A search of the EJB-INTEREST archives didn't find anything appropriate.

Any comments on this topic?


*IF* dynamic proxies are allowed, I may have discovered a bug in JBoss.

My stateful session bean stores a dynamic proxy instance. Passivation works.
Reactivation doesn't: ClassNotFoundException for the proxy interface.

A simple test case:

// Helper classes:

public interface A { }

public class AImpl implements A, Serializable { }

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
public class AInvocationHandler implements InvocationHandler, Serializable {
    private A delegate;
    public AInvocationHandler(A delegate) {
        this.delegate = delegate;
    }
    public Object invoke(Object proxy, Method m, Object[] args)
            throws Throwable {
        return m.invoke(delegate, args);
    }
}

// EJB classes:

public interface Test extends EJBObject {
    public void simpleMethod() throws RemoteException;
}

public interface TestHome extends EJBHome {
    public Test create() throws RemoteException, CreateException;
}

import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.CreateException;
public class TestBean implements SessionBean {
    private HashSet objects;
    public void ejbCreate() throws CreateException {
        objects = new HashSet();
    }
    public void simpleMethod() {
        objects.add(Proxy.newProxyInstance(A.class.getClassLoader(),
                new Class[] {A.class}, new AInvocationHandler(new AImpl())));
    }
    public void ejbRemove() { }
    public void ejbActivate() { }
    public void ejbPassivate() { }
    public void setSessionContext(SessionContext context) { }
}

// Client class:

import java.rmi.RemoteException;
import java.util.Properties;
import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class TestClient {
    public static void main(String[] args)
            throws NamingException, RemoteException, InterruptedException,
            CreateException {
        Properties props = new Properties();
        props.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
                "org.jnp.interfaces.NamingContextFactory");
        props.put(javax.naming.Context.PROVIDER_URL, "localhost:1099");
        InitialContext jndiContext = new InitialContext(props);
        TestHome testHome = (TestHome) PortableRemoteObject.narrow(
                jndiContext.lookup("Test"), TestHome.class);
        Test test = testHome.create();
        test.simpleMethod();
        System.out.println("Waiting ...");
        /* with the following settings for "Standard Stateful SessionBean"
         * in standardjboss.xml so I don't have to wait too long:
         * <overager-period>30</overager-period>
         * <max-bean-age>60</max-bean-age>
         * <resizer-period>40</resizer-period>
         */
        Thread.currentThread().sleep(150000);
        System.out.println("... finished");
        test.simpleMethod();
    }
}

The interesting part of server.log (with call-logging=true for
stateful session beans) looks like this:

[Info] Java version: 1.3.0,Sun Microsystems Inc.
[Info] Java VM: Java HotSpot(TM) Server VM 1.3.0,Sun Microsystems Inc.
[Info] System: SunOS 5.7,sparc
.
.
.
[Default] JBoss 2.2.1 Started in 0m:26s
[Test] create()
[Test] [990654535255] simpleMethod()
[Bean Cache] Resized cache for bean Test: old capacity = 1000, new capacity = 50
[Bean Cache] Scheduling for passivation overaged bean Test with id = 990654535255 - 
Cache size = 1
[Bean Cache] Aging out from cache bean Testwith id = 990654535255; cache size = 1
[Container factory] Scheduled passivation of bean Test with id = 990654535255
[Container factory] Passivated bean Test with id = 990654535255
[Test] [990654535255] simpleMethod()
[Test] Could not activate; nested exception is: 
        java.lang.ClassNotFoundException: A
[Test] java.rmi.NoSuchObjectException: Could not activate; nested exception is: 
[Test]  java.lang.ClassNotFoundException: A
[Test]  at 
org.jboss.ejb.plugins.AbstractInstanceCache.get(AbstractInstanceCache.java:173)
[Test]  at 
org.jboss.ejb.plugins.StatefulSessionInstanceInterceptor.invoke(StatefulSessionInstanceInterceptor.java:157)
[Test]  at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:195)
[Test]  at 
org.jboss.ejb.StatefulSessionContainer.invoke(StatefulSessionContainer.java:326)
[Test]  at 
org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invoke(JRMPContainerInvoker.java:392)
[Test]  at java.lang.reflect.Method.invoke(Native Method)
[Test]  at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
[Test]  at sun.rmi.transport.Transport$1.run(Transport.java:142)
[Test]  at java.security.AccessController.doPrivileged(Native Method)
[Test]  at sun.rmi.transport.Transport.serviceCall(Transport.java:139)
[Test]  at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
[Test]  at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
[Test]  at java.lang.Thread.run(Thread.java:484)

Version used: JBoss2.2.1-Tomcat3.2.1
Using JBoss standalone(run) or with EmbeddedTomcat(run_with_tomcat)
made no difference.


Looking into the source I've stumbled upon 
org.jboss.ejb.plugins.SessionObjectInputStream
which overrides ObjectInputStream's resolveClass() but not its
resolveProxyClass().
Could that be the cause?

Thanx,
        Peter

_______________________________________________
JBoss-user mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to