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

org.bimserver.plugins.classloaders.EclipsePluginClassloader Maven / Gradle / Ivy

Go to download

Shared libraries, common parent for both BIMserver and BimServerClientLib

There is a newer version: 2.0.0
Show newest version
package org.bimserver.plugins.classloaders;

/******************************************************************************
 * Copyright (C) 2009-2016  BIMserver.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see {@literal}.
 *****************************************************************************/

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.bimserver.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EclipsePluginClassloader extends PublicFindClassClassLoader {

	private static final Logger LOGGER = LoggerFactory.getLogger(EclipsePluginClassloader.class);
	private final Map> loadedClasses = new HashMap>();
	private final Path projectFolder;
	private final Path classFolder;

	public EclipsePluginClassloader(ClassLoader parentClassloader, Path projectFolder) {
		super(parentClassloader);
		this.projectFolder = projectFolder;
		this.classFolder = projectFolder.resolve("target/classes");
	}
	
	@Override
	public String toString() {
		return "EclipsePluginClassLoader: " + projectFolder.toString();
	}

	@Override
	public URL getResource(String name) {
		return findResource(name);
	}
	
	@Override
	public URL findResource(String name) {
		Path file = projectFolder.resolve(name);
		if (Files.exists(file)) {
			try {
				return file.toUri().toURL();
			} catch (MalformedURLException e) {
				LOGGER.error("", e);
			}
		}
		return null;
	}
	
	@Override
	public Class findClass(String name) throws ClassNotFoundException {
		String filename = name.replace(".", File.separator) + ".class";
		if (loadedClasses.containsKey(filename)) {
			return loadedClasses.get(filename);
		}
		Path classFile = classFolder.resolve(filename);
		if (Files.exists(classFile)) {
			try {
				byte[] bytes = IOUtils.toByteArray(Files.newInputStream(classFile));
				Class definedClass = defineClass(name, bytes, 0, bytes.length);
				if (definedClass != null) {
					loadedClasses.put(filename, definedClass);
					
					/*
					 * This is a fix to actually load the package-info.class file with
					 * the annotations about for example namespaces required for JAXB to
					 * work. Found this code here:
					 * https://issues.jboss.org/browse/JBPM-1404
					 */
					if (definedClass != null) {
						final int packageIndex = name.lastIndexOf('.');
						if (packageIndex != -1) {
							final String packageName = name.substring(0, packageIndex);
							final Package classPackage = getPackage(packageName);
							if (classPackage == null) {
								definePackage(packageName, null, null, null, null, null, null, null);
							}
						}
					}				
					
					return definedClass;
				}
			} catch (IOException e) {
				LOGGER.error("", e);
			}
		}
		throw new ClassNotFoundException(name);
	}

	public void dumpStructure(int indent) {
		System.out.print(StringUtils.gen("  ", indent));
		System.out.println("EclipsePluginClassloader " + projectFolder);
		ClassLoader parentLoader = getParent();
		if (parentLoader instanceof DelegatingClassLoader) {
			DelegatingClassLoader delegatingClassLoader = (DelegatingClassLoader)parentLoader;
			delegatingClassLoader.dumpStructure(indent + 1);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy