org.eclipse.jetty.ee.WebAppClassLoading Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.ClassMatcher;
import org.eclipse.jetty.util.component.Environment;
/**
* Common attributes and methods for configuring the {@link ClassLoader Class loading} of web application:
*
* - Protected (a.k.a. System) classes are classes typically provided by the JVM, that cannot be replaced by the
* web application, and they are always loaded via the environment or system classloader. They are visible but
* protected.
* - Hidden (a.k.a. Server) classes are those used to implement the Server and are not made available to the
* web application. They are hidden from the web application {@link ClassLoader}.
*
* These protections are set to reasonable defaults {@link #DEFAULT_PROTECTED_CLASSES} and {@link #DEFAULT_HIDDEN_CLASSES},
* which may be programmatically configured and will affect the defaults applied to all web applications in the same JVM.
*
*
* The defaults applied by a specific {@link Server} can be configured using {@link #addProtectedClasses(Server, String...)} and
* {@link #addHiddenClasses(Server, String...)}. Alternately the {@link Server} attributes {@link #PROTECTED_CLASSES_ATTRIBUTE}
* and {@link #HIDDEN_CLASSES_ATTRIBUTE} may be used to direct set a {@link ClassMatcher} to use for all web applications
* within the server instance.
*
*
* The defaults applied by a specific {@link Environment} can be configured using {@link #addProtectedClasses(Environment, String...)} and
* {@link #addHiddenClasses(Environment, String...)}. Alternately the {@link Environment} attributes {@link #PROTECTED_CLASSES_ATTRIBUTE}
* and {@link #HIDDEN_CLASSES_ATTRIBUTE} may be used to direct set a {@link ClassMatcher} to use for all web applications
* within the server instance.
*
*
* Ultimately, the configurations set by this class only affects the defaults applied to each web application
* {@link org.eclipse.jetty.server.handler.ContextHandler Context} and the {@link ClassMatcher} fields of the web applications
* can be directly access to configure a specific context.
*
*/
public class WebAppClassLoading
{
public static final String PROTECTED_CLASSES_ATTRIBUTE = "org.eclipse.jetty.webapp.systemClasses";
public static final String HIDDEN_CLASSES_ATTRIBUTE = "org.eclipse.jetty.webapp.serverClasses";
/**
* The default protected (system) classes used by a web application, which will be applied to the {@link ClassMatcher}s created
* by {@link #getProtectedClasses(Environment)}.
*/
public static final ClassMatcher DEFAULT_PROTECTED_CLASSES = new ClassMatcher(
"java.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
"javax.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
"jakarta.", // Jakarta classes (per servlet spec v5.0 / Section 15.2.1)
"org.xml.", // javax.xml
"org.w3c." // javax.xml
);
/**
* The default hidden (server) classes used by a web application, which can be applied to the {@link ClassMatcher}s created
* by {@link #getHiddenClasses(Environment)}.
*/
public static final ClassMatcher DEFAULT_HIDDEN_CLASSES = new ClassMatcher(
"org.eclipse.jetty." // hide jetty classes
);
/**
* Get the default protected (system) classes for a {@link Server}
* @param server The {@link Server} for the defaults
* @return The default protected (system) classes for the {@link Server}, which will be empty if not previously configured.
*/
public static ClassMatcher getProtectedClasses(Server server)
{
return getClassMatcher(server, PROTECTED_CLASSES_ATTRIBUTE, null);
}
/**
* Get the default protected (system) classes for an {@link Environment}
* @param environment The {@link Server} for the defaults
* @return The default protected (system) classes for the {@link Environment}, which will be the {@link #DEFAULT_PROTECTED_CLASSES} if not previously configured.
*/
public static ClassMatcher getProtectedClasses(Environment environment)
{
return getClassMatcher(environment, PROTECTED_CLASSES_ATTRIBUTE, DEFAULT_PROTECTED_CLASSES);
}
/**
* Add a protected (system) Class pattern to use for all WebAppContexts.
* @param patterns the patterns to use
*/
public static void addProtectedClasses(String... patterns)
{
DEFAULT_PROTECTED_CLASSES.add(patterns);
}
/**
* Add a protected (system) Class pattern to use for all WebAppContexts of a given {@link Server}.
* @param attributes The {@link Attributes} instance to add classes to
* @param patterns the patterns to use
*/
public static void addProtectedClasses(Attributes attributes, String... patterns)
{
if (patterns != null && patterns.length > 0)
getClassMatcher(attributes, PROTECTED_CLASSES_ATTRIBUTE, null).add(patterns);
}
/**
* Add a protected (system) Class pattern to use for all WebAppContexts of a given {@link Server}.
* @param server The {@link Server} instance to add classes to
* @param patterns the patterns to use
*/
public static void addProtectedClasses(Server server, String... patterns)
{
if (patterns != null && patterns.length > 0)
getClassMatcher(server, PROTECTED_CLASSES_ATTRIBUTE, null).add(patterns);
}
/**
* Add a protected (system) Class pattern to use for WebAppContexts of a given environment.
* @param environment The {@link Environment} instance to add classes to
* @param patterns the patterns to use
*/
public static void addProtectedClasses(Environment environment, String... patterns)
{
if (patterns != null && patterns.length > 0)
getClassMatcher(environment, PROTECTED_CLASSES_ATTRIBUTE, DEFAULT_PROTECTED_CLASSES).add(patterns);
}
/**
* Get the default hidden (server) classes for a {@link Server}
* @param server The {@link Server} for the defaults
* @return The default hidden (server) classes for the {@link Server}, which will be empty if not previously configured.
*
*/
public static ClassMatcher getHiddenClasses(Server server)
{
return getClassMatcher(server, HIDDEN_CLASSES_ATTRIBUTE, null);
}
/**
* Get the default hidden (server) classes for an {@link Environment}
* @param environment The {@link Server} for the defaults
* @return The default hidden (server) classes for the {@link Environment}, which will be {@link #DEFAULT_PROTECTED_CLASSES} if not previously configured.
*/
public static ClassMatcher getHiddenClasses(Environment environment)
{
return getClassMatcher(environment, HIDDEN_CLASSES_ATTRIBUTE, DEFAULT_HIDDEN_CLASSES);
}
/**
* Add a hidden (server) Class pattern to use for all WebAppContexts of a given {@link Server}.
* @param patterns the patterns to use
*/
public static void addHiddenClasses(String... patterns)
{
DEFAULT_HIDDEN_CLASSES.add(patterns);
}
/**
* Add a hidden (server) Class pattern to use for all WebAppContexts of a given {@link Server}.
* @param attributes The {@link Attributes} instance to add classes to
* @param patterns the patterns to use
*/
public static void addHiddenClasses(Attributes attributes, String... patterns)
{
if (patterns != null && patterns.length > 0)
getClassMatcher(attributes, HIDDEN_CLASSES_ATTRIBUTE, null).add(patterns);
}
/**
* Add a hidden (server) Class pattern to use for all WebAppContexts of a given {@link Server}.
* @param server The {@link Server} instance to add classes to
* @param patterns the patterns to use
*/
public static void addHiddenClasses(Server server, String... patterns)
{
if (patterns != null && patterns.length > 0)
getClassMatcher(server, HIDDEN_CLASSES_ATTRIBUTE, null).add(patterns);
}
/**
* Add a hidden (server) Class pattern to use for all ee9 WebAppContexts.
* @param environment The {@link Environment} instance to add classes to
* @param patterns the patterns to use
*/
public static void addHiddenClasses(Environment environment, String... patterns)
{
if (patterns != null && patterns.length > 0)
getClassMatcher(environment, HIDDEN_CLASSES_ATTRIBUTE, DEFAULT_HIDDEN_CLASSES).add(patterns);
}
private static ClassMatcher getClassMatcher(Attributes attributes, String attribute, ClassMatcher defaultPatterns)
{
Object existing = attributes.getAttribute(attribute);
if (existing instanceof ClassMatcher cm)
return cm;
ClassMatcher classMatcher = (existing instanceof String[] stringArray)
? new ClassMatcher(stringArray) : new ClassMatcher(defaultPatterns);
attributes.setAttribute(attribute, classMatcher);
return classMatcher;
}
}