Author: cziegeler
Date: Fri Aug 13 16:06:21 2010
New Revision: 985256

URL: http://svn.apache.org/viewvc?rev=985256&view=rev
Log:
SLING-1631 : Classloading problems when taglibs are used

Removed:
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/Activator.java
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/TaglibCache.java
Modified:
    sling/trunk/bundles/scripting/jsp/pom.xml
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/JspScriptEngineFactory.java
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/SlingTldLocationsCache.java
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/JspCompilationContext.java
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/TagFileProcessor.java
    
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServletWrapper.java

Modified: sling/trunk/bundles/scripting/jsp/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/pom.xml?rev=985256&r1=985255&r2=985256&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp/pom.xml (original)
+++ sling/trunk/bundles/scripting/jsp/pom.xml Fri Aug 13 16:06:21 2010
@@ -51,9 +51,6 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
-                        <Bundle-Activator>
-                            org.apache.sling.scripting.jsp.Activator
-                        </Bundle-Activator>
                         <Export-Package>
                             org.apache.sling.scripting.jsp.jasper.runtime;
                             org.apache.sling.scripting.jsp.util;version=2.0.8,

Modified: 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/JspScriptEngineFactory.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/JspScriptEngineFactory.java?rev=985256&r1=985255&r2=985256&view=diff
==============================================================================
--- 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/JspScriptEngineFactory.java
 (original)
+++ 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/JspScriptEngineFactory.java
 Fri Aug 13 16:06:21 2010
@@ -37,6 +37,7 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.SlingException;
+import org.apache.sling.api.SlingIOException;
 import org.apache.sling.api.SlingServletException;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.scripting.SlingBindings;
@@ -102,8 +103,7 @@ public class JspScriptEngineFactory
     /** The io provider for reading and writing. */
     private SlingIOProvider ioProvider;
 
-    @Reference
-    private TaglibCache tldLocationsCache;
+    private SlingTldLocationsCache tldLocationsCache;
 
     private JspRuntimeContext jspRuntimeContext;
 
@@ -217,12 +217,14 @@ public class JspScriptEngineFactory
         Thread.currentThread().setContextClassLoader(jspClassLoader);
 
         try {
+            this.tldLocationsCache = new 
SlingTldLocationsCache(componentContext.getBundleContext());
+
             // prepare some classes
             ioProvider = new SlingIOProvider(classLoaderWriter);
 
             // return options which use the jspClassLoader
             options = new JspServletOptions(slingServletContext, ioProvider,
-                componentContext, jspClassLoader, 
(SlingTldLocationsCache)tldLocationsCache);
+                componentContext, jspClassLoader, tldLocationsCache);
 
             // Initialize the JSP Runtime Context
             this.jspRuntimeContext = new JspRuntimeContext(slingServletContext,
@@ -232,7 +234,7 @@ public class JspScriptEngineFactory
             this.jspRuntimeContext.setIOProvider(ioProvider);
 
             jspServletContext = new JspServletContext(ioProvider,
-                slingServletContext, 
(SlingTldLocationsCache)tldLocationsCache);
+                slingServletContext, tldLocationsCache);
 
             servletConfig = new JspServletConfig(jspServletContext,
                 componentContext.getProperties());
@@ -261,6 +263,10 @@ public class JspScriptEngineFactory
     protected void deactivate(final ComponentContext componentContext) {
         logger.debug("JspScriptEngine.deactivate()");
 
+        if ( this.tldLocationsCache != null ) {
+            
this.tldLocationsCache.deactivate(componentContext.getBundleContext());
+            this.tldLocationsCache = null;
+        }
         if ( this.eventHandlerRegistration != null ) {
             this.eventHandlerRegistration.unregister();
             this.eventHandlerRegistration = null;

Modified: 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/SlingTldLocationsCache.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/SlingTldLocationsCache.java?rev=985256&r1=985255&r2=985256&view=diff
==============================================================================
--- 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/SlingTldLocationsCache.java
 (original)
+++ 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/SlingTldLocationsCache.java
 Fri Aug 13 16:06:21 2010
@@ -20,6 +20,7 @@ import java.io.InputStream;
 import java.net.URL;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.sling.scripting.jsp.jasper.JasperException;
@@ -28,18 +29,21 @@ import org.apache.sling.scripting.jsp.ja
 import org.apache.sling.scripting.jsp.jasper.xmlparser.TreeNode;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
 
 /**
  * The <code>SlingTldLocationsCache</code> TODO
  */
 public class SlingTldLocationsCache
-    extends TldLocationsCache implements TaglibCache {
+    extends TldLocationsCache implements BundleListener {
 
     private static final String TLD_SCHEME = "tld:";
 
     private final Map<String, TldLocationEntry> tldLocations = new 
HashMap<String, TldLocationEntry>();
 
     public SlingTldLocationsCache(final BundleContext context) {
+        context.addBundleListener(this);
         final Bundle[] bundles = context.getBundles();
         for (int i = 0; i < bundles.length; i++) {
             if (bundles[i].getState() == Bundle.RESOLVED || 
bundles[i].getState() == Bundle.ACTIVE ) {
@@ -48,8 +52,20 @@ public class SlingTldLocationsCache
         }
     }
 
+    public void deactivate(final BundleContext context) {
+        context.removeBundleListener(this);
+    }
+
     // ---------- Tld Location URL support 
-------------------------------------
 
+    public void bundleChanged(final BundleEvent event) {
+        if ( event.getType() == BundleEvent.RESOLVED ) {
+            this.addBundle(event.getBundle());
+        } else if ( event.getType() == BundleEvent.UNRESOLVED ) {
+            this.removeBundle(event.getBundle());
+        }
+    }
+
     URL getTldLocationURL(String tldLocation) {
         if (tldLocation.startsWith(TLD_SCHEME)) {
             tldLocation = tldLocation.substring(TLD_SCHEME.length());
@@ -79,7 +95,7 @@ public class SlingTldLocationsCache
         return null;
     }
 
-    public void addBundle(Bundle bundle) {
+    private void addBundle(final Bundle bundle) {
         // currently only META-INF/*.tld is supported, this should
         // be extended for registration in a Bundle Manifest Header
 
@@ -99,15 +115,16 @@ public class SlingTldLocationsCache
         }
     }
 
-    public boolean isBundleUsed(Bundle bundle) {
+    private void removeBundle(final Bundle bundle) {
         synchronized (tldLocations) {
-            for(final TldLocationEntry tle : tldLocations.values()) {
-                if (tle.getBundleId() == bundle.getBundleId()) {
-                    return true;
+            final Iterator<Map.Entry<String, TldLocationEntry>> i = 
tldLocations.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry<String, TldLocationEntry> entry = i.next();
+                if (entry.getValue().getBundleId() == bundle.getBundleId()) {
+                    i.remove();
                 }
             }
         }
-        return false;
     }
 
     /*

Modified: 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/JspCompilationContext.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/JspCompilationContext.java?rev=985256&r1=985255&r2=985256&view=diff
==============================================================================
--- 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/JspCompilationContext.java
 (original)
+++ 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/JspCompilationContext.java
 Fri Aug 13 16:06:21 2010
@@ -36,7 +36,6 @@ import org.apache.sling.scripting.jsp.ja
 import org.apache.sling.scripting.jsp.jasper.compiler.JspUtil;
 import org.apache.sling.scripting.jsp.jasper.compiler.Localizer;
 import org.apache.sling.scripting.jsp.jasper.compiler.ServletWriter;
-import org.apache.sling.scripting.jsp.jasper.servlet.JasperLoader;
 import org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper;
 
 /**
@@ -79,13 +78,11 @@ public class JspCompilationContext {
     protected String baseURI;
     protected String outputDir;
     protected ServletContext context;
-    protected ClassLoader loader;
 
     protected JspRuntimeContext rctxt;
 
     protected int removed = 0;
 
-    protected ClassLoader jspLoader;
     protected URL baseUrl;
     protected Class<?> servletClass;
 
@@ -148,45 +145,36 @@ public class JspCompilationContext {
 
     /**
      * The classpath that is passed off to the Java compiler.
-     */
     public String getClassPath() {
         if( classPath != null )
             return classPath;
         return rctxt.getClassPath();
     }
+     */
 
     /**
      * The classpath that is passed off to the Java compiler.
-     */
     public void setClassPath(String classPath) {
         this.classPath = classPath;
     }
+     */
 
     /**
      * What class loader to use for loading classes while compiling
      * this JSP?
      */
     public ClassLoader getClassLoader() {
-        if( loader != null )
-            return loader;
-        return rctxt.getParentClassLoader();
+        return getJspLoader();
     }
 
+    /**
     public void setClassLoader(ClassLoader loader) {
         this.loader = loader;
     }
+     */
 
     public ClassLoader getJspLoader() {
-        if( jspLoader == null ) {
-            ClassLoader jspLoader = options.getJspClassLoader();
-            if (jspLoader == null) {
-                jspLoader = new JasperLoader(new URL[] { baseUrl },
-                    getClassLoader(), rctxt.getPermissionCollection(),
-                    rctxt.getCodeSource());
-            }
-            this.jspLoader = jspLoader;
-        }
-        return jspLoader;
+        return options.getJspClassLoader();
     }
 
     /** ---------- Input/Output  ---------- */
@@ -608,7 +596,6 @@ public class JspCompilationContext {
         if (isPackagedTagFile || jspCompiler.isOutDated()) {
             try {
                 jspCompiler.removeGeneratedFiles();
-                jspLoader = null;
                 jspCompiler.compile();
                 jsw.setReload(true);
                 jsw.setCompilationException(null);
@@ -649,7 +636,7 @@ public class JspCompilationContext {
             } else {
                 name = getServletPackageName() + "." + getServletClassName();
             }
-            servletClass = jspLoader.loadClass(name);
+            servletClass = getJspLoader().loadClass(name);
         } catch (ClassNotFoundException cex) {
             throw new 
JasperException(Localizer.getMessage("jsp.error.unable.load"),
                                       cex);

Modified: 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/TagFileProcessor.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/TagFileProcessor.java?rev=985256&r1=985255&r2=985256&view=diff
==============================================================================
--- 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/TagFileProcessor.java
 (original)
+++ 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/TagFileProcessor.java
 Fri Aug 13 16:06:21 2010
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,10 +19,10 @@ package org.apache.sling.scripting.jsp.j
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
-import java.util.HashMap;
 
 import javax.el.MethodExpression;
 import javax.el.ValueExpression;
@@ -42,7 +42,7 @@ import org.apache.sling.scripting.jsp.ja
 /**
  * 1. Processes and extracts the directive info in a tag file. 2. Compiles and
  * loads tag files used in a JSP file.
- * 
+ *
  * @author Kin-man Chung
  */
 
@@ -236,7 +236,7 @@ class TagFileProcessor {
             if (deferredMethod && deferredValue) {
                 err.jspError(n, "jsp.error.deferredmethodandvalue");
             }
-            
+
             String attrName = n.getAttributeValue("name");
             boolean required = JspUtil.booleanValue(n
                     .getAttributeValue("required"));
@@ -263,7 +263,7 @@ class TagFileProcessor {
             } else {
                 if (type == null)
                     type = "java.lang.String";
-                
+
                 if (deferredValue) {
                     type = ValueExpression.class.getName();
                 } else if (deferredMethod) {
@@ -276,7 +276,7 @@ class TagFileProcessor {
                             || deferredValueSpecified || deferredValue)) {
                 err.jspError("jsp.error.invalid.version", path);
             }
-            
+
             TagAttributeInfo tagAttributeInfo = new TagAttributeInfo(attrName,
                     required, type, rtexprvalue, fragment, null, deferredValue,
                     deferredMethod, deferredValueType, 
deferredMethodSignature);
@@ -423,14 +423,14 @@ class TagFileProcessor {
         /**
          * Reports a translation error if names specified in attributes of
          * directives are not unique in this translation unit.
-         * 
+         *
          * The value of the following attributes must be unique. 1. 'name'
          * attribute of an attribute directive 2. 'name-given' attribute of a
          * variable directive 3. 'alias' attribute of variable directive 4.
          * 'dynamic-attributes' of a tag directive except that
          * 'dynamic-attributes' can (and must) have the same value when it
          * appears in multiple tag directives.
-         * 
+         *
          * Also, 'name-from' attribute of a variable directive cannot have the
          * same value as that from another variable directive.
          */
@@ -491,7 +491,7 @@ class TagFileProcessor {
      * in it. The method is used to obtain the info on the tag file, when the
      * handler that it represents is referenced. The tag file is not compiled
      * here.
-     * 
+     *
      * @param pc
      *            the current ParserController used in this compilation
      * @param name
@@ -533,7 +533,7 @@ class TagFileProcessor {
 
         JspCompilationContext ctxt = compiler.getCompilationContext();
         JspRuntimeContext rctxt = ctxt.getRuntimeContext();
-        JspServletWrapper wrapper = (JspServletWrapper) rctxt
+        JspServletWrapper wrapper = rctxt
                 .getWrapper(tagFilePath);
 
         synchronized (rctxt) {
@@ -544,8 +544,8 @@ class TagFileProcessor {
                 rctxt.addWrapper(tagFilePath, wrapper);
 
                 // Use same classloader and classpath for compiling tag files
-                
wrapper.getJspEngineContext().setClassLoader(ctxt.getClassLoader());
-                
wrapper.getJspEngineContext().setClassPath(ctxt.getClassPath());
+                
//wrapper.getJspEngineContext().setClassLoader(ctxt.getClassLoader());
+                
//wrapper.getJspEngineContext().setClassPath(ctxt.getClassPath());
             } else {
                 // Make sure that JspCompilationContext gets the latest TagInfo
                 // for the tag file. TagInfo instance was created the last
@@ -646,7 +646,7 @@ class TagFileProcessor {
     /**
      * Removed the java and class files for the tag prototype generated from 
the
      * current compilation.
-     * 
+     *
      * @param classFileName
      *            If non-null, remove only the class file with with this name.
      */

Modified: 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServletWrapper.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServletWrapper.java?rev=985256&r1=985255&r2=985256&view=diff
==============================================================================
--- 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServletWrapper.java
 (original)
+++ 
sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServletWrapper.java
 Fri Aug 13 16:06:21 2010
@@ -221,9 +221,14 @@ public class JspServletWrapper {
             }
             if (firstTime || this.lastModificationTest == 0) {
                 synchronized (this) {
-                    ctxt.compile();
-                    firstTime = false;
-                    this.lastModificationTest = System.currentTimeMillis();
+                    if (firstTime || this.lastModificationTest == 0 ) {
+                        ctxt.compile();
+                        this.lastModificationTest = System.currentTimeMillis();
+                        firstTime = false;
+                    } else if ( compileException != null ) {
+                        // Throw cached compilation exception
+                        throw compileException;
+                    }
                 }
             } else {
                 if (compileException != null) {
@@ -231,9 +236,18 @@ public class JspServletWrapper {
                 }
             }
 
+            if (!reload) {
+                if ( tagHandlerClass.getClassLoader() instanceof 
DynamicClassLoader ) {
+                    reload = 
!((DynamicClassLoader)tagHandlerClass.getClassLoader()).isLive();
+                }
+            }
             if (reload) {
-                tagHandlerClass = ctxt.load();
-                reload = false;
+                synchronized ( this ) {
+                    if ( reload ) {
+                        tagHandlerClass = ctxt.load();
+                        reload = false;
+                    }
+                }
             }
         } catch (IOException ex) {
             throw new JasperException(ex);
@@ -266,9 +280,18 @@ public class JspServletWrapper {
         try {
             Object target;
             if (isTagFile) {
+                if (!reload) {
+                    if ( tagHandlerClass.getClassLoader() instanceof 
DynamicClassLoader ) {
+                        reload = 
!((DynamicClassLoader)tagHandlerClass.getClassLoader()).isLive();
+                    }
+                }
                 if (reload) {
-                    tagHandlerClass = ctxt.load();
-                    reload = false;
+                    synchronized ( this ) {
+                        if ( reload ) {
+                            tagHandlerClass = ctxt.load();
+                            reload = false;
+                        }
+                    }
                 }
                 target = tagHandlerClass.newInstance();
             } else {


Reply via email to