Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (C) 2015 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/package org.bonitasoft.engine.classloader;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.bonitasoft.engine.classloader.listeners.ClassReflectorClearer;
import org.bonitasoft.engine.classloader.listeners.JacksonCacheClearer;
import org.bonitasoft.engine.commons.NullCheckingUtil;
import org.bonitasoft.engine.events.EventService;
import org.bonitasoft.engine.events.model.SEvent;
import org.bonitasoft.engine.events.model.impl.SEventImpl;
import org.bonitasoft.engine.exception.BonitaHomeNotSetException;
import org.bonitasoft.engine.home.BonitaHomeServer;
import org.bonitasoft.engine.log.technical.TechnicalLogSeverity;
import org.bonitasoft.engine.log.technical.TechnicalLoggerService;
/**
* @author Elias Ricken de Medeiros
* @author Baptiste Mesta
* @author Matthieu Chaffotte
*/publicclassClassLoaderServiceImplimplementsClassLoaderService{
privatefinal ParentClassLoaderResolver parentClassLoaderResolver;
privatefinal TechnicalLoggerService logger;
private VirtualClassLoader virtualGlobalClassLoader = new VirtualClassLoader(ClassLoaderIdentifier.GLOBAL_TYPE, ClassLoaderIdentifier.GLOBAL_ID, VirtualClassLoader.class.getClassLoader());
privatefinal Map localClassLoaders = new HashMap<>();
privatefinal Set globalListeners = new HashSet<>();
privatefinal Object mutex = new ClassLoaderServiceMutex();
privateboolean shuttingDown = false;
privatefinal EventService eventService;
privateboolean traceEnabled;
publicClassLoaderServiceImpl(final ParentClassLoaderResolver parentClassLoaderResolver, final TechnicalLoggerService logger,
final EventService eventService){
this.parentClassLoaderResolver = parentClassLoaderResolver;
this.logger = logger;
this.eventService = eventService;
traceEnabled = logger.isLoggable(this.getClass(), TechnicalLogSeverity.TRACE);
globalListeners.add(new ClassReflectorClearer());
globalListeners.add(new JacksonCacheClearer());
// BS-9304 : Create the temporary directory with the IOUtil class, to delete it at the end of the JVM
}
privatestaticfinalclassClassLoaderServiceMutex{
}
private ClassLoaderIdentifier getKey(final String type, finallong id){
returnnew ClassLoaderIdentifier(type, id);
}
@OverridepubliclonggetGlobalClassLoaderId(){
return ClassLoaderIdentifier.GLOBAL_ID;
}
@Overridepublic String getGlobalClassLoaderType(){
return ClassLoaderIdentifier.GLOBAL_TYPE;
}
private VirtualClassLoader getVirtualGlobalClassLoader(){
return virtualGlobalClassLoader;
}
@Overridepublic ClassLoader getGlobalClassLoader(){
return getVirtualGlobalClassLoader();
}
privatevoidwarnOnShuttingDown(final ClassLoaderIdentifier key){
if (shuttingDown && logger.isLoggable(getClass(), TechnicalLogSeverity.WARNING)) {
logger.log(getClass(), TechnicalLogSeverity.WARNING, "Using local classloader on after ClassLoaderService shuttingdown: " + key);
}
}
@Overridepublic VirtualClassLoader getLocalClassLoader(final String type, finallong id){
NullCheckingUtil.checkArgsNotNull(id, type);
final ClassLoaderIdentifier key = getKey(type, id);
return getLocalClassLoader(key);
}
private VirtualClassLoader getLocalClassLoader(ClassLoaderIdentifier key){
warnOnShuttingDown(key);
if (!localClassLoaders.containsKey(key)) {
synchronized (mutex) {
// double check synchronizationif (!localClassLoaders.containsKey(key)) {
createClassLoader(key);
}
}
}
return localClassLoaders.get(key);
}
privatevoidcreateClassLoader(ClassLoaderIdentifier identifier){
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "creating classloader with key " + identifier);
}
VirtualClassLoader parent = getParentClassLoader(identifier);
final VirtualClassLoader virtualClassLoader = new VirtualClassLoader(identifier.getType(), identifier.getId(), parent);
localClassLoaders.put(identifier, virtualClassLoader);
}
private VirtualClassLoader getParentClassLoader(ClassLoaderIdentifier identifier){
final ClassLoaderIdentifier parentIdentifier = parentClassLoaderResolver.getParentClassLoaderIdentifier(identifier);
NullCheckingUtil.checkArgsNotNull(parentIdentifier);
VirtualClassLoader parent;
if (ClassLoaderIdentifier.GLOBAL.equals(parentIdentifier)) {
parent = getVirtualGlobalClassLoader();
} else {
parent = getLocalClassLoader(parentIdentifier);
}
return parent;
}
@OverridepublicvoidremoveLocalClassLoader(final String type, finallong id)throws SClassLoaderException {
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Removing local classloader for type " + type + " of id " + id);
}
NullCheckingUtil.checkArgsNotNull(id, type);
// Remove the class loaderfinal ClassLoaderIdentifier key = getKey(type, id);
destroyLocalClassLoader(key);
}
privatevoiddestroyLocalClassLoader(final ClassLoaderIdentifier key)throws SClassLoaderException {
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Destroying local classloader with key: " + key);
}
final VirtualClassLoader localClassLoader = localClassLoaders.get(key);
if (localClassLoader != null) {
if (localClassLoader.hasChildren()) {
thrownew SClassLoaderException("Unable to delete classloader " + key + " because it has children: " + localClassLoader.getChildren());
}
localClassLoader.destroy();
localClassLoaders.remove(key);
for (ClassLoaderListener globalListener : globalListeners) {
globalListener.onDestroy(localClassLoader);
}
}
}
@OverridepublicvoidrefreshGlobalClassLoader(final Map resources)throws SClassLoaderException {
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Refreshing global classloader");
}
final VirtualClassLoader virtualClassloader = (VirtualClassLoader) getGlobalClassLoader();
try {
refreshClassLoader(virtualClassloader, resources, getGlobalClassLoaderType(), getGlobalClassLoaderId(),
BonitaHomeServer.getInstance().getGlobalTemporaryFolder(),
ClassLoaderServiceImpl.class.getClassLoader());
} catch (Exception e) {
thrownew SClassLoaderException(e);
}
}
@OverridepublicvoidrefreshLocalClassLoader(final String type, finallong id, final Map resources)throws SClassLoaderException {
final ClassLoaderIdentifier key = getKey(type, id);
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Refreshing local classloader with key: " + key);
}
final VirtualClassLoader virtualClassloader = getLocalClassLoader(type, id);
try {
refreshClassLoader(virtualClassloader, resources, type, id, getLocalTemporaryFolder(type, id),
getParentClassLoader(key));
final SEvent event = new SEventImpl("ClassLoaderRefreshed");
event.setObject(key);
eventService.fireEvent(event);
} catch (Exception e) {
thrownew SClassLoaderException(e);
}
}
protected URI getLocalTemporaryFolder(String type, long id)throws BonitaHomeNotSetException, IOException {
return BonitaHomeServer.getInstance().getLocalTemporaryFolder(type, id);
}
privatevoidrefreshClassLoader(final VirtualClassLoader virtualClassloader, final Map resources, final String type, finallong id,
final URI temporaryFolder, final ClassLoader parent){
final BonitaClassLoader classLoader = new BonitaClassLoader(resources, type, id, temporaryFolder, parent);
virtualClassloader.replaceClassLoader(classLoader);
for (ClassLoaderListener globalListener : new HashSet<>(globalListeners)) {
globalListener.onUpdate(virtualClassloader);
}
}
@Overridepublicvoidstart(){
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Starting classloader service, creating the platform classloader");
}
shuttingDown = false;
//we do not create or destroy the global classloader because it does not point to a bonita classloader
}
@Overridepublicvoidstop()throws SClassLoaderException {
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Stopping classloader service, destroying all classloaders");
}
shuttingDown = true;
destroyAllLocalClassLoaders();
}
privatevoiddestroyAllLocalClassLoaders()throws SClassLoaderException {
if (traceEnabled) {
logger.log(this.getClass(), TechnicalLogSeverity.TRACE, "Destroying all classloaders");
}
//remove elements only that don't have children//there is no loop in this so the algorithm finishesfinal Set> entries = localClassLoaders.entrySet();
while (!entries.isEmpty()) {
final Iterator> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry next = iterator.next();
if (!next.getValue().hasChildren()) {
next.getValue().destroy();
iterator.remove();
}
}
}
}
@Overridepublicvoidpause(){
}
@Overridepublicvoidresume(){
}
@OverridepublicbooleanaddListener(String type, long id, ClassLoaderListener classLoaderListener){
logger.log(getClass(), TechnicalLogSeverity.DEBUG, "Added listener " + classLoaderListener + " on " + type + " " + id);
final VirtualClassLoader localClassLoader = getLocalClassLoader(type, id);
return localClassLoader.addListener(classLoaderListener);
}
@OverridepublicbooleanremoveListener(String type, long id, ClassLoaderListener classLoaderListener){
logger.log(getClass(), TechnicalLogSeverity.DEBUG, "Removed listener " + classLoaderListener + " on " + type + " " + id);
VirtualClassLoader localClassLoader = getLocalClassLoader(type, id);
return localClassLoader.removeListener(classLoaderListener);
}
@OverridepublicbooleanaddListener(ClassLoaderListener classLoaderListener){
logger.log(getClass(), TechnicalLogSeverity.DEBUG, "Added global listener " + classLoaderListener);
return globalListeners.add(classLoaderListener);
}
@OverridepublicbooleanremoveListener(ClassLoaderListener classLoaderListener){
logger.log(getClass(), TechnicalLogSeverity.DEBUG, "Removed global listener " + classLoaderListener);
return globalListeners.remove(classLoaderListener);
}
}