/* ******************************************************************* * Copyright (c) 2003 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v 2.0 * which accompanies this distribution and is available at * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt * * Contributors: * Isberg initial implementation * ******************************************************************/ package org.aspectj.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * Load classes as File from File[] dirs or URL[] jars. */ public class UtilClassLoader extends URLClassLoader { /** seek classes in dirs first */ List dirs; /** save URL[] only for toString */ private URL[] urlsForDebugString; public UtilClassLoader(URL[] urls, File[] dirs) { super(urls); LangUtil.throwIaxIfNotAssignable(dirs, File.class, "dirs"); this.urlsForDebugString = urls; List dcopy = new ArrayList<>(); if (!LangUtil.isEmpty(dirs)) { dcopy.addAll(Arrays.asList(dirs)); } this.dirs = Collections.unmodifiableList(dcopy); } public URL getResource(String name) { return ClassLoader.getSystemResource(name); } public InputStream getResourceAsStream(String name) { return ClassLoader.getSystemResourceAsStream(name); } public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // search the cache, our dirs (if maybe test), // the system, the superclass (URL[]), // and our dirs again (if not maybe test) ClassNotFoundException thrown = null; Class result = findLoadedClass(name); if (null != result) { resolve = false; } else { try { result = findSystemClass(name); } catch (ClassNotFoundException e) { thrown = e; } } if (null == result) { try { result = super.loadClass(name, resolve); } catch (ClassNotFoundException e) { thrown = e; } if (null != result) { // resolved by superclass return result; } } if (null == result) { byte[] data = readClass(name); if (data != null) { result = defineClass(name, data, 0, data.length); } // handle ClassFormatError? } if (null == result) { throw (null != thrown ? thrown : new ClassNotFoundException(name)); } if (resolve) { resolveClass(result); } return result; } /** @return null if class not found or byte[] of class otherwise */ private byte[] readClass(String className) throws ClassNotFoundException { final String fileName = className.replace('.', '/')+".class"; for (File dir : dirs) { File file = new File(dir, fileName); if (file.canRead()) { return getClassData(file); } } return null; } private byte[] getClassData(File f) { try { FileInputStream stream= new FileInputStream(f); ByteArrayOutputStream out= new ByteArrayOutputStream(1000); byte[] b= new byte[4096]; int n; while ((n= stream.read(b)) != -1) { out.write(b, 0, n); } stream.close(); out.close(); return out.toByteArray(); } catch (IOException e) { } return null; } /** @return String with debug info: urls and classes used */ public String toString() { return "UtilClassLoader(urls=" + Arrays.asList(urlsForDebugString) + ", dirs=" + dirs + ")"; } }