java.net.bytebuddy.dynamic.loading.InjectionClassLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of securemock Show documentation
Show all versions of securemock Show documentation
Libraries for Elasticsearch
The newest version!
/*
* Copyright 2014 - 2018 Rafael Winterhalter
*
* Licensed 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 net.bytebuddy.dynamic.loading;
import net.bytebuddy.description.type.TypeDescription;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
*
* An injection class loader allows for the injection of a class after the class loader was created. Injection is only possible if this class loader is not sealed.
*
*
* Important: Not sealing a class loader allows to break package encapsulation for anybody getting hold of a reference to this class loader.
*
*/
public abstract class InjectionClassLoader extends ClassLoader {
/**
* Indicates if this class loader is sealed, i.e. forbids runtime injection.
*/
private final boolean sealed;
/**
* Creates a new injection class loader.
*
* @param parent The class loader's parent.
* @param sealed Indicates if this class loader is sealed, i.e. forbids runtime injection.
*/
protected InjectionClassLoader(ClassLoader parent, boolean sealed) {
super(parent);
this.sealed = sealed;
}
/**
* Returns {@code true} if this class loader is sealed.
*
* @return {@code true} if this class loader is sealed.
*/
public boolean isSealed() {
return sealed;
}
/**
* Defines a new type to be loaded by this class loader.
*
* @param name The name of the type.
* @param binaryRepresentation The type's binary representation.
* @return The defined class or a previously defined class.
* @throws ClassNotFoundException If the class could not be loaded.
*/
public Class> defineClass(String name, byte[] binaryRepresentation) throws ClassNotFoundException {
return defineClasses(Collections.singletonMap(name, binaryRepresentation)).get(name);
}
/**
* Defines a group of types to be loaded by this class loader. If this class loader is sealed, an {@link IllegalStateException} is thrown.
*
* @param typeDefinitions The types binary representations.
* @return The mapping of defined classes or previously defined classes by their name.
* @throws ClassNotFoundException If the class could not be loaded.
*/
public Map> defineClasses(Map typeDefinitions) throws ClassNotFoundException {
if (sealed) {
throw new IllegalStateException("Cannot inject classes into a sealed class loader");
}
return doDefineClasses(typeDefinitions);
}
/**
* Defines a group of types to be loaded by this class loader.
*
* @param typeDefinitions The types binary representations.
* @return The mapping of defined classes or previously defined classes by their name.
* @throws ClassNotFoundException If the class could not be loaded.
*/
protected abstract Map> doDefineClasses(Map typeDefinitions) throws ClassNotFoundException;
/**
* A class loading strategy for adding a type to an injection class loader.
*/
public enum Strategy implements ClassLoadingStrategy {
/**
* The singleton instance.
*/
INSTANCE;
/**
* {@inheritDoc}
*/
public Map> load(InjectionClassLoader classLoader, Map types) {
if (classLoader == null) {
throw new IllegalArgumentException("Cannot add types to bootstrap class loader: " + types);
}
Map typeDefinitions = new LinkedHashMap();
Map typeDescriptions = new HashMap();
for (Map.Entry entry : types.entrySet()) {
typeDefinitions.put(entry.getKey().getName(), entry.getValue());
typeDescriptions.put(entry.getKey().getName(), entry.getKey());
}
Map> loadedTypes = new HashMap>();
try {
for (Map.Entry> entry : classLoader.defineClasses(typeDefinitions).entrySet()) {
loadedTypes.put(typeDescriptions.get(entry.getKey()), entry.getValue());
}
} catch (ClassNotFoundException exception) {
throw new IllegalStateException("Cannot load classes: " + types, exception);
}
return loadedTypes;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy