Even though the change worked on the 2.4 codebase, it was not really
satsifactory. (This is why I have not commited it.) I am attaching a small
patchfile in unified diff format, so you could take this stuff into
account when restoring the dynamic class loading. This "solution" is just 
FYI (not a patch submission), as it has a number of problems:

1) It breaks modularization by explicitly referring to the class
   org.jboss.proxy.compiler.IIOPStubCompiler, which is in the iiop module.

2) It runs the IIOPStubCompiler for every class not found whose name ends
   with _Stub, even if the class does not belong to an IIOP-deployed EJB.

3) When the IIOPContainerInvoker needs to obtain the codebase to be
   embedded into an IOR, it is currenty doing an awful hack:

   ((WebClassLoader)container.getClassLoader().getParent()).getURLs()

4) It does not address the issue of making codebases constant over time.
   Codebases that will go into persistent CORBA references (for entity
   EJBObjects or EJBHomes) should have this property.

Problem 1) and 2) could be solved by making the deployer get the "web
classloader class name" from the bean metadata. Default class names
would be specified by the container configurations in standardjboss.xml.

One way to get rid of the crappy code in 3) would be to associate a
codebase directly with the container. By the time the deployer registers a
web classloader with the WebServer, it could also set the containers'  
codebase.

To solve problem 4), the WebServer's loaderMap should use stable
classloader keys, at least for the classloaders that correspond to
IIOP-deployed EJBs. Something like the bean's JNDI name could be used
rather than cl.hashCode(). 

I would appreciate your advice on the best way to proceed. Please let me
know if/when I should start implementing something along these lines.

Best,

Francisco


On Tue, 12 Feb 2002, Scott M Stark wrote:

> I think it was thrown out in the last coding frenzy. I am going
> to restore dynamic class loading so you can submit the patch
> for 2.4 and I'll integrate into main.
> 
> xxxxxxxxxxxxxxxxxxxxxxxx
> Scott Stark
> Chief Technology Officer
> JBoss Group, LLC
> xxxxxxxxxxxxxxxxxxxxxxxx
> ----- Original Message -----
> From: "Francisco Reverbel" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Tuesday, February 12, 2002 3:17 PM
> Subject: [JBoss-dev] Help on WebClassLoader
> 
> 
> > I have an uncommitted change on org.jboss.web.WebClassLoader to enable
> > downloading of IIOP stubs. This change worked fine on the 2.4 codebase.
> >
> > On the 3.0 codebase, however, it appears that org.jboss.web.WebClassLoader
> > is not being used anymore... Am I right here? If so, which class is now
> > used by org.jboss.web.WebServer to do dynamic loading of classes from
> > deployed jars?
> >
> > Best,
> >
> > Francisco
Index: server/src/main/org/jboss/web/WebClassLoader.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/web/WebClassLoader.java,v
retrieving revision 1.2
diff -u -r1.2 WebClassLoader.java
--- server/src/main/org/jboss/web/WebClassLoader.java   18 Jun 2001 20:01:29 -0000     
 1.2
+++ server/src/main/org/jboss/web/WebClassLoader.java   13 Feb 2002 13:45:40 -0000
@@ -2,6 +2,12 @@
 
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.jboss.logging.Logger;
+import org.jboss.proxy.compiler.IIOPStubCompiler;
 
 /** A simple subclass of URLClassLoader that overrides the getURLs()
 method to return a different set of URLs for remote loading than what is used
@@ -19,9 +25,15 @@
 */
 public class WebClassLoader extends URLClassLoader
 {
+    /** Logger for trace messages */
+    static Logger logger = Logger.getLogger(WebClassLoader.class);
+
     /** The URLs returned by the getURLs() method override */
     private URL[] webURLs;
 
+    /** Map from stub classes into bytecode arrays (stub bytecode cache) */
+    private Map loadedStubMap = Collections.synchronizedMap(new WeakHashMap());
+
     /** Creates new WebClassLoader */
     public WebClassLoader(URL[] urls)
     {
@@ -64,4 +76,63 @@
     {
         this.webURLs = webURLs;
     }
+
+    public byte[] getBytes(Class clz) {
+        byte[] code = (byte[])loadedStubMap.get(clz);
+        return (code == null) ? null : (byte[])code.clone();
+    }
+   
+    protected  Class findClass(String name) 
+        throws ClassNotFoundException 
+    {
+        if (logger.isTraceEnabled()) {
+            logger.trace("findClass(" + name + ") called");
+        }
+        if (name.endsWith("_Stub")) {
+            int start = name.lastIndexOf('.') + 1;
+            if (name.charAt(start) == '_') {
+                String pkg = name.substring(0, start);
+                String interfaceName = pkg + name.substring(start + 1, 
+                                                            name.length() - 5);
+                Class intf = super.loadClass(interfaceName);
+                if (logger.isTraceEnabled()) {
+                    logger.trace("loaded class " + interfaceName);
+                }
+                
+                try {
+                    byte[] code = 
+                        IIOPStubCompiler.compile(intf, name);
+               
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("compiled stub class for " 
+                                     + interfaceName);
+                    }
+                    Class clz = defineClass(name, code, 0, code.length);
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("defined stub class for " 
+                                     + interfaceName);
+                    }
+                    resolveClass(clz);
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("resolved stub class for " 
+                                     + interfaceName);
+                    }
+                    loadedStubMap.put(clz, code);
+                    return clz;
+                }
+                catch (RuntimeException e) {
+                    logger.error("failed finding class " + name, e);
+                    //throw e;
+                    return super.findClass(name);
+                }
+            }
+            else {
+                return super.findClass(name);
+            }
+        }
+        else {
+            return super.findClass(name);
+        }
+    }
+
 }
Index: server/src/main/org/jboss/web/WebServer.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/web/WebServer.java,v
retrieving revision 1.17
diff -u -r1.17 WebServer.java
--- server/src/main/org/jboss/web/WebServer.java        5 Jan 2002 12:08:54 -0000      
 1.17
+++ server/src/main/org/jboss/web/WebServer.java        13 Feb 2002 13:45:40 -0000
@@ -293,15 +293,22 @@
                     Class clazz = loader.loadClass(className);
                     URL clazzUrl = 
clazz.getProtectionDomain().getCodeSource().getLocation();
                     log.trace("clazzUrl = "+clazzUrl);
-                    if (clazzUrl.getFile().endsWith(".jar"))
-                       clazzUrl = new URL("jar:"+clazzUrl+"!/"+filePath);
-                    else
-                       clazzUrl = new URL(clazzUrl, filePath);
-                    if (clazzUrl == null)
-                     throw new Exception("Class not found:"+className);
-              
-                    // Retrieve bytecodes
-                    bytes = getBytes(clazzUrl);
+
+                    if (clazzUrl == null) {
+                        bytes = 
+((WebClassLoader)clazz.getClassLoader()).getBytes(clazz);
+                        if (bytes == null)
+                            throw new Exception("Class not found: " 
+                                                + className);
+                    }
+                    else {
+                        if (clazzUrl.getFile().endsWith(".jar"))
+                            clazzUrl = new URL("jar:"+clazzUrl+"!/"+filePath);
+                        else
+                            clazzUrl = new URL(clazzUrl, filePath);
+                        
+                        // Retrieve bytecodes
+                        bytes = getBytes(clazzUrl);
+                    }
                 }
                 else if( loader != null && filePath.length() > 0 && 
downloadServerClasses )
                 {

Reply via email to