All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jasper.servlet.JasperLoader Maven / Gradle / Ivy

/*
 * 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.jasper.servlet;

import static org.apache.jasper.JasperMessages.MESSAGES;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedExceptionAction;

import org.apache.jasper.Constants;

/**
 * Class loader for loading servlet class files (corresponding to JSP files)
 * and tag handler class files (corresponding to tag files).
 *
 * @author Anil K. Vijendran
 * @author Harish Prabandham
 */
public class JasperLoader extends URLClassLoader {

    private final PermissionCollection permissionCollection;
    private final ClassLoader parent;
    private final SecurityManager securityManager;
    private final CodeSource codeSource;
    private final AccessControlContext acc;

    public JasperLoader(URL[] urls, ClassLoader parent,
                        PermissionCollection permissionCollection, CodeSource codeSource) {
	super(urls, parent);
	    this.permissionCollection = permissionCollection;
	    this.parent = parent;
        this.codeSource = codeSource;
        this.securityManager = System.getSecurityManager();
        this.acc = AccessController.getContext();
    }

     /**
     * Load the class with the specified name.  This method searches for
     * classes in the same manner as loadClass(String, boolean)
     * with false as the second argument.
     *
     * @param name Name of the class to be loaded
     *
     * @exception ClassNotFoundException if the class was not found
     */
    @Override
    public Class loadClass(String name) throws ClassNotFoundException {

        return (loadClass(name, false));
    }

    /**
     * Load the class with the specified name, searching using the following
     * algorithm until it finds and returns the class.  If the class cannot
     * be found, returns ClassNotFoundException.
     * 
    *
  • Call findLoadedClass(String) to check if the * class has already been loaded. If it has, the same * Class object is returned.
  • *
  • If the delegate property is set to true, * call the loadClass() method of the parent class * loader, if any.
  • *
  • Call findClass() to find this class in our locally * defined repositories.
  • *
  • Call the loadClass() method of our parent * class loader, if any.
  • *
* If the class was found using the above steps, and the * resolve flag is true, this method will then * call resolveClass(Class) on the resulting Class object. * * @param name Name of the class to be loaded * @param resolve If true then resolve the class * * @exception ClassNotFoundException if the class was not found */ @Override public synchronized Class loadClass(final String name, boolean resolve) throws ClassNotFoundException { Class clazz = null; // (0) Check our previously loaded class cache clazz = findLoadedClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return (clazz); } // (.5) Permission to access this class when using a SecurityManager if (securityManager != null) { int dot = name.lastIndexOf('.'); if (dot >= 0) { try { // Do not call the security manager since by default, we grant that package. if (!"org.apache.jasper.runtime".equalsIgnoreCase(name.substring(0,dot))){ securityManager.checkPackageAccess(name.substring(0,dot)); } } catch (SecurityException se) { throw new ClassNotFoundException(MESSAGES.securityExceptionLoadingClass(name), se); } } } if( !name.startsWith(Constants.JSP_PACKAGE_NAME + '.') ) { // Class is not in org.apache.jsp, therefore, have our // parent load it clazz = parent.loadClass(name); if( resolve ) resolveClass(clazz); return clazz; } return findClass(name); } @Override protected Class findClass(final String name) throws ClassNotFoundException { try { return AccessController.doPrivileged( new PrivilegedExceptionAction() { public Class run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); URL res = findResource(path); if (res != null) { try { byte[] bytes = getBytes(res); return defineClass(name, bytes, 0, bytes.length, codeSource); } catch (IOException e) { throw new ClassNotFoundException(name, e); } } else { throw new ClassNotFoundException(name); } } }, acc); } catch (java.security.PrivilegedActionException pae) { throw (ClassNotFoundException) pae.getException(); } } private byte[] getBytes(URL resource)throws IOException{ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try (InputStream stream = resource.openStream()){ byte[] chunk = new byte[4096]; int bytesRead; while ((bytesRead = stream.read(chunk)) > 0) { outputStream.write(chunk, 0, bytesRead); } } return outputStream.toByteArray(); } /** * Delegate to parent * * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String) */ @Override public InputStream getResourceAsStream(String name) { InputStream is = parent.getResourceAsStream(name); if (is == null) { URL url = findResource(name); if (url != null) { try { is = url.openStream(); } catch (IOException e) { // Ignore } } } return is; } /** * Get the Permissions for a CodeSource. * * Since this ClassLoader is only used for a JSP page in * a web application context, we just return our preset * PermissionCollection for the web app context. * * @param codeSource Code source where the code was loaded from * @return PermissionCollection for CodeSource */ @Override public final PermissionCollection getPermissions(CodeSource codeSource) { return permissionCollection; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy