2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.drools.serverpooltest;
24 import java.util.ArrayList;
25 import java.util.Enumeration;
26 import java.util.HashSet;
27 import java.util.NoSuchElementException;
30 * Ordinarily, a 'ClassLoader' first attempts to load a class via the
31 * parent 'ClassLoader'. If that fails, it attempts to load it "locally"
32 * by whatever mechanism the class loader supports.
33 * This 'ClassLoader' instance blocks attempts to load specific classes,
34 * throwing a 'ClassNotFoundException'. This doesn't seem useful on the
35 * surface, but it forces all child 'ClassLoader' instances to do the lookup
36 * themselves. In addition, each child 'ClassLoader' will have their own
37 * copy of the classes they load, providing a way to have multiple copies of
38 * the same class running within the same JVM. Each child 'ClassLoader' can
39 * be viewed as having a separate name space.
41 public class BlockingClassLoader extends ClassLoader {
42 // these are the set of packages to block
43 private HashSet<String> packages;
45 // these are the prefixes of class names to block
46 private ArrayList<String> prefixes;
48 // these specific classes will not be blocked, even if they are in one
49 // of the packages indicated by 'packages'
50 private HashSet<String> excludes = new HashSet<String>();
52 // these are the prefixes of class names to exclude
53 private ArrayList<String> excludePrefixes = new ArrayList<>();
56 * Constructor -- initialize the 'ClassLoader' and 'packages' variable.
58 * @param parent the parent ClassLoader
59 * @param packages variable number of packages to block
61 public BlockingClassLoader(ClassLoader parent, String... packages) {
63 this.packages = new HashSet<>();
64 this.prefixes = new ArrayList<>();
65 for (String pkg : packages) {
66 if (pkg.endsWith("*")) {
67 prefixes.add(pkg.substring(0, pkg.length() - 1));
69 this.packages.add(pkg);
78 protected Class<?> findClass(String name) throws ClassNotFoundException {
79 // throws a 'ClassNotFoundException' if we are blocking this one
82 // not blocking this one -- pass it on to the superclass
83 return super.findClass(name);
90 public Enumeration<URL> getResources(String name) {
91 // in order to avoid replicated resources, we return an empty set
92 return new Enumeration<URL>() {
93 public boolean hasMoreElements() {
97 public URL nextElement() {
98 throw new NoSuchElementException("'BlockingClassLoader' blocks duplicate resources");
107 public Class<?> loadClass(String name) throws ClassNotFoundException {
108 // throws a 'ClassNotFoundException' if we are blocking this one
111 // not blocking this one -- pass it on to the superclass
112 return super.loadClass(name);
119 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
120 // throws a 'ClassNotFoundException' if we are blocking this one
123 // not blocking this one -- pass it on to the superclass
124 return super.loadClass(name, resolve);
128 * Add an entry to the list of classes that should NOT be blocked.
130 * @param name the full name of a class that shouldn't be blocked
132 public void addExclude(String name) {
133 if (name.endsWith("*")) {
134 excludePrefixes.add(name.substring(0, name.length() - 1));
141 * This method looks at a class name -- if it should be blocked, a
142 * 'ClassNotFoundException' is thrown. Otherwise, it does nothing.
144 * @param name the name of the class to be tested
145 * @throws ClassNotFoundException if this class should be blocked
147 private void testClass(String name) throws ClassNotFoundException {
148 if (excludes.contains(name)) {
153 for (String prefix : excludePrefixes) {
154 if (name.startsWith(prefix)) {
160 // extract the package from the class name -- throw a
161 // 'ClassNotFoundException' if the package is in the list
163 int index = name.lastIndexOf('.');
165 if (packages.contains(name.substring(0,index))) {
166 throw(new ClassNotFoundException(name));
169 for (String prefix : prefixes) {
170 if (name.startsWith(prefix)) {
171 throw(new ClassNotFoundException(name));