Modified: sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JDTCompiler.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JDTCompiler.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JDTCompiler.java (original) +++ sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JDTCompiler.java Fri Mar 23 14:53:38 2012 @@ -76,7 +76,7 @@ public class JDTCompiler extends org.apa final String targetClassName = ((packageName.length() != 0) ? (packageName + ".") : "") + ctxt.getServletClassName(); - final ClassLoader classLoader = ctxt.getJspLoader(); + final ClassLoader classLoader = ctxt.getClassLoader(); String[] fileNames = new String[] {sourceFile}; String[] classNames = new String[] {targetClassName}; final ArrayList problemList = new ArrayList();
Modified: sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JspRuntimeContext.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JspRuntimeContext.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JspRuntimeContext.java (original) +++ sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/JspRuntimeContext.java Fri Mar 23 14:53:38 2012 @@ -80,7 +80,7 @@ public final class JspRuntimeContext { private int jspReloadCount; /** The {@link IOProvider} used to get access to output */ - private IOProvider ioProvider = IOProvider.DEFAULT; + private final IOProvider ioProvider; /** This is a delegate forwarding either to our own factory * or the original one. @@ -210,10 +210,11 @@ public final class JspRuntimeContext { * * @param context ServletContext for web application */ - public JspRuntimeContext(ServletContext context, Options options) { + public JspRuntimeContext(ServletContext context, Options options, final IOProvider ioProvider) { this.context = context; this.options = options; + this.ioProvider = ioProvider; // Get the parent class loader parentClassLoader = Thread.currentThread().getContextClassLoader(); @@ -451,19 +452,6 @@ public final class JspRuntimeContext { return ioProvider; } - /** - * Sets the {@link IOProvider} to use in this context. - * - * @param ioProvider The {@link IOProvider} to use in this context. - * If this is <code>null</code> the {@link IOProvider#DEFAULT default} - * provider is set. - */ - public void setIOProvider(IOProvider ioProvider) { - this.ioProvider = (ioProvider == null) - ? IOProvider.DEFAULT - : ioProvider; - } - // -------------------------------------------------------- Private Methods @@ -490,12 +478,9 @@ public final class JspRuntimeContext { } } - cpath.append(options.getScratchDir() + sep); + cpath.append(options.getScratchDir() + sep); String cp = (String) context.getAttribute(Constants.SERVLET_CLASSPATH); - if (cp == null || cp.equals("")) { - cp = options.getClassPath(); - } classpath = cpath.toString() + cp; Modified: sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServlet.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServlet.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServlet.java (original) +++ sling/trunk/bundles/scripting/jsp/src/main/java/org/apache/sling/scripting/jsp/jasper/servlet/JspServlet.java Fri Mar 23 14:53:38 2012 @@ -96,7 +96,7 @@ public class JspServlet extends HttpServ // Use the default Options implementation options = new EmbeddedServletOptions(config, context); } - rctxt = new JspRuntimeContext(context, options); + rctxt = new JspRuntimeContext(context, options, null); if (log.isDebugEnabled()) { log.debug(Localizer.getMessage("jsp.message.scratch.dir.is", Modified: sling/trunk/contrib/commons/compiler/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/contrib/commons/compiler/pom.xml?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/commons/compiler/pom.xml (original) +++ sling/trunk/contrib/commons/compiler/pom.xml Fri Mar 23 14:53:38 2012 @@ -94,7 +94,7 @@ <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.commons.classloader</artifactId> - <version>1.1.0</version> + <version>1.2.5-SNAPSHOT</version> <scope>provided</scope> </dependency> <dependency> Modified: sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java (original) +++ sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java Fri Mar 23 14:53:38 2012 @@ -19,6 +19,7 @@ package org.apache.sling.commons.compile import java.util.ArrayList; import java.util.List; +import org.apache.sling.commons.classloader.ClassLoaderWriter; import org.apache.sling.commons.compiler.CompilationResult; import org.apache.sling.commons.compiler.CompilerMessage; @@ -35,25 +36,25 @@ public class CompilationResultImpl imple private final boolean compilationRequired; - private final ClassLoader classLoader; + private final ClassLoaderWriter classLoaderWriter; public CompilationResultImpl(final String errorMessage) { this.ignoreWarnings = true; - this.classLoader = null; + this.classLoaderWriter = null; this.compilationRequired = false; this.onError(errorMessage, "<General>", 0, 0); } - public CompilationResultImpl(final ClassLoader classLoader) { + public CompilationResultImpl(final ClassLoaderWriter writer) { this.ignoreWarnings = true; - this.classLoader = classLoader; + this.classLoaderWriter = writer; this.compilationRequired = false; } public CompilationResultImpl(final boolean ignoreWarnings, - final ClassLoader classLoader) { + final ClassLoaderWriter writer) { this.ignoreWarnings = ignoreWarnings; - this.classLoader = classLoader; + this.classLoaderWriter = writer; this.compilationRequired = true; } @@ -79,7 +80,7 @@ public class CompilationResultImpl imple if ( errors != null ) { throw new ClassNotFoundException(className); } - return this.classLoader.loadClass(className); + return this.classLoaderWriter.getClassLoader().loadClass(className); } /** Modified: sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java (original) +++ sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java Fri Mar 23 14:53:38 2012 @@ -29,10 +29,8 @@ import java.util.Map; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferencePolicy; import org.apache.felix.scr.annotations.Service; import org.apache.sling.commons.classloader.ClassLoaderWriter; -import org.apache.sling.commons.classloader.DynamicClassLoaderManager; import org.apache.sling.commons.compiler.CompilationResult; import org.apache.sling.commons.compiler.CompilationUnit; import org.apache.sling.commons.compiler.JavaCompiler; @@ -65,14 +63,9 @@ public class EclipseJavaCompiler impleme /** Logger instance */ private final Logger logger = LoggerFactory.getLogger(EclipseJavaCompiler.class); - @Reference(policy=ReferencePolicy.DYNAMIC) + @Reference private ClassLoaderWriter classLoaderWriter; - @Reference(policy=ReferencePolicy.DYNAMIC) - private DynamicClassLoaderManager dynamicClassLoaderManager; - - private ClassLoader classLoader; - /** the static problem factory */ private IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); @@ -80,52 +73,15 @@ public class EclipseJavaCompiler impleme private final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems(); /** - * Bind the class load provider. - * @param repositoryClassLoaderProvider the new provider - */ - protected void bindDynamicClassLoaderManager(final DynamicClassLoaderManager rclp) { - if ( this.classLoader != null ) { - this.ungetClassLoader(); - } - this.getClassLoader(rclp); - } - - /** - * Unbind the class loader provider. - * @param repositoryClassLoaderProvider the old provider - */ - protected void unbindDynamicClassLoaderManager(final DynamicClassLoaderManager rclp) { - if ( this.dynamicClassLoaderManager == rclp ) { - this.ungetClassLoader(); - } - } - - /** - * Get the commons dynamic class loader - */ - private void getClassLoader(final DynamicClassLoaderManager rclp) { - this.dynamicClassLoaderManager = rclp; - this.classLoader = rclp.getDynamicClassLoader(); - } - - /** - * Unget the commons dynamic class loader - */ - private void ungetClassLoader() { - this.classLoader = null; - this.dynamicClassLoaderManager = null; - } - - /** * Get the classloader for the compilation. */ - private ClassLoader getClassLoader(final Options options) { + private ClassLoader getClassLoader(final Options options, final ClassLoaderWriter classLoaderWriter) { final ClassLoader loader; if ( options.get(Options.KEY_CLASS_LOADER) != null ) { loader = (ClassLoader)options.get(Options.KEY_CLASS_LOADER); } else if ( options.get(Options.KEY_ADDITIONAL_CLASS_LOADER) != null ) { final ClassLoader additionalClassLoader = (ClassLoader)options.get(Options.KEY_ADDITIONAL_CLASS_LOADER); - loader = new ClassLoader(this.classLoader) { + loader = new ClassLoader(classLoaderWriter.getClassLoader()) { protected Class<?> findClass(String name) throws ClassNotFoundException { return additionalClassLoader.loadClass(name); @@ -136,7 +92,7 @@ public class EclipseJavaCompiler impleme } }; } else { - loader = this.classLoader; + loader = classLoaderWriter.getClassLoader(); } return loader; } @@ -197,14 +153,14 @@ public class EclipseJavaCompiler impleme final Options options = (compileOptions != null ? compileOptions : EMPTY_OPTIONS); // get classloader and classloader writer - final ClassLoader loader = this.getClassLoader(options); - if ( loader == null ) { - return new CompilationResultImpl("Class loader for compilation is not available."); - } final ClassLoaderWriter writer = this.getClassLoaderWriter(options); if ( writer == null ) { return new CompilationResultImpl("Class loader writer for compilation is not available."); } + final ClassLoader loader = this.getClassLoader(options, writer); + if ( loader == null ) { + return new CompilationResultImpl("Class loader for compilation is not available."); + } // check sources for compilation boolean needsCompilation = isForceCompilation(options); @@ -218,7 +174,7 @@ public class EclipseJavaCompiler impleme } if ( !needsCompilation ) { logger.debug("All source files are recent - no compilation required."); - return new CompilationResultImpl(loader); + return new CompilationResultImpl(writer); } // delete old class files @@ -248,7 +204,7 @@ public class EclipseJavaCompiler impleme logger.debug("Compiling with settings {}.", settings); // create the result - final CompilationResultImpl result = new CompilationResultImpl(isIgnoreWarnings(options), loader); + final CompilationResultImpl result = new CompilationResultImpl(isIgnoreWarnings(options), writer); // create the context final CompileContext context = new CompileContext(units, result, writer, loader); Added: sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java?rev=1304391&view=auto ============================================================================== --- sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java (added) +++ sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java Fri Mar 23 14:53:38 2012 @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sling.commons.compiler.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.security.SecureClassLoader; + +import org.apache.sling.commons.classloader.ClassLoaderWriter; + + +/** + * The <code>IsolatedClassLoader</code> class loads classes through + * the class loader writer + */ +public final class IsolatedClassLoader + extends SecureClassLoader { + + private final ClassLoaderWriter classLoaderWriter; + + public IsolatedClassLoader(final ClassLoader parent, + final ClassLoaderWriter classLoaderWriter) { + super(parent); + this.classLoaderWriter = classLoaderWriter; + } + + + //---------- Class loader overwrites ------------------------------------- + + /** + * Loads the class from this <code>ClassLoader</class>. If the + * class does not exist in this one, we check the parent. Please + * note that this is the exact opposite of the + * <code>ClassLoader</code> spec. We use it to work around + * inconsistent class loaders from third party vendors. + * + * @param name the name of the class + * @param resolve if <code>true</code> then resolve the class + * @return the resulting <code>Class</code> object + * @exception ClassNotFoundException if the class could not be found + */ + public final Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + // First check if it's already loaded + Class<?> clazz = findLoadedClass(name); + + if (clazz == null) { + + try { + clazz = findClass(name); + } catch (final ClassNotFoundException cnfe) { + final ClassLoader parent = getParent(); + if (parent != null) { + // Ask to parent ClassLoader (can also throw a CNFE). + clazz = parent.loadClass(name); + } else { + // Propagate exception + throw cnfe; + } + } + } + + if (resolve) { + resolveClass(clazz); + } + + return clazz; + } + + /** + * Finds and loads the class with the specified name from the class path. + * + * @param name the name of the class + * @return the resulting class + * + * @throws ClassNotFoundException If the named class could not be found or + * if this class loader has already been destroyed. + */ + protected Class<?> findClass(final String name) throws ClassNotFoundException { + try { + return AccessController.doPrivileged( + new PrivilegedExceptionAction<Class<?>>() { + + public Class<?> run() throws ClassNotFoundException { + return findClassPrivileged(name); + } + }); + } catch (final java.security.PrivilegedActionException pae) { + throw (ClassNotFoundException) pae.getException(); + } + } + + /** + * Tries to find the class in the class path from within a + * <code>PrivilegedAction</code>. Throws <code>ClassNotFoundException</code> + * if no class can be found for the name. + * + * @param name the name of the class + * + * @return the resulting class + * + * @throws ClassNotFoundException if the class could not be found + * @throws NullPointerException If this class loader has already been + * destroyed. + */ + private Class<?> findClassPrivileged(final String name) throws ClassNotFoundException { + // prepare the name of the class + final String path = "/" + name.replace('.', '/') + ".class"; + InputStream is = null; + try { + is = this.classLoaderWriter.getInputStream(path); + final Class<?> c = defineClass(name, is); + if (c == null) { + throw new ClassNotFoundException(name); + } + return c; + } catch ( final ClassNotFoundException cnfe) { + throw cnfe; + } catch (final Throwable t) { + throw new ClassNotFoundException(name, t); + } + } + + /** + * Defines a class getting the bytes for the class from the resource + * + * @param name The fully qualified class name + * @param is The resource to obtain the class bytes from + * + * @throws IOException If a problem occurrs reading the class bytes from + * the resource. + * @throws ClassFormatError If the class bytes read from the resource are + * not a valid class. + */ + private Class<?> defineClass(final String name, final InputStream is) + throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final byte[] buffer = new byte[2048]; + int l; + while ( ( l = is.read(buffer)) >= 0 ) { + baos.write(buffer, 0, l); + } + final byte[] data = baos.toByteArray(); + return defineClass(name, data, 0, data.length); + } +} Propchange: sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java ------------------------------------------------------------------------------ svn:keywords = author date id revision rev url Propchange: sling/trunk/contrib/commons/compiler/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: sling/trunk/contrib/commons/compiler/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/commons/compiler/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/commons/compiler/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java (original) +++ sling/trunk/contrib/commons/compiler/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java Fri Mar 23 14:53:38 2012 @@ -113,4 +113,11 @@ public class CompilerJava5Test extends T public boolean rename(String oldPath, String newPath) { return false; } + + /** + * @see org.apache.sling.commons.classloader.ClassLoaderWriter#getClassLoader() + */ + public ClassLoader getClassLoader() { + return null; + } } Modified: sling/trunk/contrib/scripting/java/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/java/pom.xml?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/scripting/java/pom.xml (original) +++ sling/trunk/contrib/scripting/java/pom.xml Fri Mar 23 14:53:38 2012 @@ -80,6 +80,10 @@ <dependencies> <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + </dependency> + <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> <version>2.0.8</version> Modified: sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java (original) +++ sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java Fri Mar 23 14:53:38 2012 @@ -31,6 +31,11 @@ import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; import org.apache.sling.api.SlingConstants; import org.apache.sling.api.SlingException; import org.apache.sling.api.SlingHttpServletRequest; @@ -52,16 +57,17 @@ import org.osgi.service.event.EventHandl /** * The Java engine * - * @scr.component label="%javahandler.name" description="%javahandler.description" - * @scr.property name="service.description" value="Java Servlet Script Handler" - * @scr.property name="service.vendor" value="The Apache Software Foundation" - * @scr.service interface="javax.script.ScriptEngineFactory" - * - * @scr.property nameRef="PROPERTY_COMPILER_SOURCE_V_M" valueRef="DEFAULT_VM_VERSION" - * @scr.property nameRef="PROPERTY_COMPILER_TARGET_V_M" valueRef="DEFAULT_VM_VERSION" - * @scr.property nameRef="PROPERTY_CLASSDEBUGINFO" value="true" type="Boolean" - * @scr.property nameRef="PROPERTY_ENCODING" value="UTF-8" */ +@Component(metatype=true, label="%javahandler.name", description="%javahandler.description") +@Service(value=javax.script.ScriptEngineFactory.class) +@Properties({ + @Property(name="service.vendor", value="The Apache Software Foundation"), + @Property(name="service.description", value="Java Servlet Script Handler"), + @Property(name=JavaScriptEngineFactory.PROPERTY_COMPILER_SOURCE_V_M, value=JavaScriptEngineFactory.DEFAULT_VM_VERSION), + @Property(name=JavaScriptEngineFactory.PROPERTY_COMPILER_TARGET_V_M, value=JavaScriptEngineFactory.DEFAULT_VM_VERSION), + @Property(name=JavaScriptEngineFactory.PROPERTY_CLASSDEBUGINFO, boolValue=true), + @Property(name=JavaScriptEngineFactory.PROPERTY_ENCODING, value="UTF-8") +}) public class JavaScriptEngineFactory extends AbstractScriptEngineFactory implements EventHandler { @@ -77,12 +83,10 @@ public class JavaScriptEngineFactory /** Default source and target VM version (value is "1.5"). */ public static final String DEFAULT_VM_VERSION = "1.5"; - /** - * @scr.reference - */ + @Reference private JavaCompiler javaCompiler; - /** @scr.reference */ + @Reference private ServletContext slingServletContext; private SlingIOProvider ioProvider; Modified: sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java?rev=1304391&r1=1304390&r2=1304391&view=diff ============================================================================== --- sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java (original) +++ sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java Fri Mar 23 14:53:38 2012 @@ -21,7 +21,6 @@ import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -68,9 +67,6 @@ public class ServletWrapper { /** Flag for handling modifications. */ private volatile long lastModificationTest = 0L; - /** The compiled class. */ - private volatile Class<?> theServletClass; - /** * The compiled and instantiated servlet. This field may be null in which case a new servlet * instance is created per request. @@ -106,7 +102,6 @@ public class ServletWrapper { public void service(HttpServletRequest request, HttpServletResponse response) throws Exception { - Servlet servlet = null; try { if ((available > 0L) && (available < Long.MAX_VALUE)) { if (available > System.currentTimeMillis()) { @@ -136,7 +131,7 @@ public class ServletWrapper { throw compileException; } - servlet = getServlet(); + final Servlet servlet = this.getServlet(); // invoke the servlet if (servlet instanceof SingleThreadModel) { @@ -149,7 +144,7 @@ public class ServletWrapper { servlet.service(request, response); } - } catch (UnavailableException ex) { + } catch (final UnavailableException ex) { int unavailableSeconds = ex.getUnavailableSeconds(); if (unavailableSeconds <= 0) { unavailableSeconds = 60; // Arbitrary default @@ -160,10 +155,6 @@ public class ServletWrapper { (HttpServletResponse.SC_SERVICE_UNAVAILABLE, ex.getMessage()); logger.error("Java servlet {} is unavailable.", this.sourcePath); - } finally { - if (servlet != null && theServlet == null) { - servlet.destroy(); - } } } @@ -189,8 +180,8 @@ public class ServletWrapper { * Check if the used classloader is still valid */ private boolean checkReload() { - if ( theServletClass != null && theServletClass.getClassLoader() instanceof DynamicClassLoader ) { - return !((DynamicClassLoader)theServletClass.getClassLoader()).isLive(); + if ( theServlet != null && theServlet.getClass().getClassLoader() instanceof DynamicClassLoader ) { + return !((DynamicClassLoader)theServlet.getClass().getClassLoader()).isLive(); } return false; } @@ -205,25 +196,17 @@ public class ServletWrapper { if (this.checkReload()) { synchronized (this) { if (this.checkReload()) { + logger.debug("Reloading {}", this.sourcePath); this.compile(); } } } - if (theServlet == null && theServletClass != null) { - final Servlet servlet = (Servlet) theServletClass.newInstance(); - servlet.init(this.config); - - injectFields(servlet); - - return servlet; - } - return theServlet; } - private void injectFields(Servlet servlet) { - for (Field field : theServletClass.getDeclaredFields()) { + private void injectFields(final Servlet servlet) { + for (Field field : servlet.getClass().getDeclaredFields()) { if (field.isAnnotationPresent(Inject.class)) { field.setAccessible(true); try { @@ -254,16 +237,16 @@ public class ServletWrapper { logger.warn("Field {} of {} was not an injectable collection type.", field.getName(), sourcePath); continue; } - + Class<?> serviceType = (Class<?>) ptype.getActualTypeArguments()[0]; Object[] services = scriptHelper.getServices(serviceType, null); field.set(servlet, Arrays.asList(services)); } else { logger.warn("Field {} of {} was not an injectable type.", field.getName(), sourcePath); } - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { logger.error(String.format("Unable to inject into field %s of %s.", field.getName(), sourcePath), e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { logger.error(String.format("Unable to inject into field %s of %s.", field.getName(), sourcePath), e); } finally { field.setAccessible(false); @@ -288,19 +271,18 @@ public class ServletWrapper { opts); final List<CompilerMessage> errors = result.getErrors(); + this.destroy(); if ( errors != null && errors.size() > 0 ) { throw CompilerException.create(errors, this.sourcePath); } - if ( result.didCompile() || this.theServletClass == null ) { - destroy(); - this.theServletClass = result.loadCompiledClass(this.className); - } - if ( !hasInjectedFields(this.theServletClass) ) { - final Servlet servlet = (Servlet) theServletClass.newInstance(); - servlet.init(this.config); - this.theServlet = servlet; - } + final Servlet servlet = (Servlet) result.loadCompiledClass(this.className).newInstance(); + + servlet.init(this.config); + this.injectFields(servlet); + + this.theServlet = servlet; + } catch (final Exception ex) { // store exception for futher access attempts this.compileException = ex; @@ -310,15 +292,6 @@ public class ServletWrapper { } } - private static boolean hasInjectedFields(Class<?> clazz) { - for (Field field : clazz.getDeclaredFields()) { - if (field.isAnnotationPresent(Inject.class)) { - return true; - } - } - return false; - } - /** Compiler exception .*/ protected final static class CompilerException extends ServletException {
